001/*
002 * The contents of this file are subject to the license and copyright
003 * detailed in the LICENSE and NOTICE files at the root of the source
004 * tree.
005 */
006
007package org.fcrepo.camel.toolbox.app;
008
009import org.slf4j.Logger;
010import org.springframework.context.annotation.AnnotationConfigApplicationContext;
011import picocli.CommandLine;
012
013import java.nio.file.Path;
014import java.util.concurrent.Callable;
015import java.util.concurrent.CountDownLatch;
016
017import static org.fcrepo.camel.common.config.BasePropsConfig.FCREPO_CAMEL_CONFIG_FILE_PROPERTY;
018import static org.slf4j.LoggerFactory.getLogger;
019
020//TODO pull in version and git revision from generated property file
021
022/**
023 * The command line tool entry point and parameter definitions
024 *
025 * @author dbernstein
026 */
027@CommandLine.Command(name = "fcrepo-camel-toolbox",
028        mixinStandardHelpOptions = true, sortOptions = false,
029        versionProvider = AppVersionProvider.class)
030public class Driver implements Callable<Integer> {
031
032    private static final Logger LOGGER = getLogger(Driver.class);
033
034
035    @CommandLine.Option(names = {"--config", "-c"}, required = false, order = 1,
036            description = "The path to the configuration file")
037    private Path configurationFilePath;
038
039    @Override
040    public Integer call() {
041
042        if (configurationFilePath != null) {
043            System.setProperty(FCREPO_CAMEL_CONFIG_FILE_PROPERTY, configurationFilePath.toFile().getAbsolutePath());
044        }
045        final var appContext = new AnnotationConfigApplicationContext("org.fcrepo.camel");
046        final var countdownLatch = new CountDownLatch(1);
047
048        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
049            LOGGER.info("Shutting down fcrepo-camel-toolbox...");
050            appContext.stop();
051            countdownLatch.countDown();
052        }));
053        appContext.start();
054        LOGGER.info("fcrepo-camel-toolbox started.");
055        try {
056            countdownLatch.await();
057        } catch (final InterruptedException e) {
058            // Ignore error because we are exiting anyways.
059            return 1;
060        }
061        return 0;
062    }
063
064    /**
065     * @param args Command line arguments
066     */
067    public static void main(final String[] args) {
068        final Driver driver = new Driver();
069        final CommandLine cmd = new CommandLine(driver);
070        cmd.setExecutionExceptionHandler(new AppExceptionHandler(driver));
071        cmd.execute(args);
072    }
073
074    private static class AppExceptionHandler implements CommandLine.IExecutionExceptionHandler {
075
076        private final Driver driver;
077
078        AppExceptionHandler(final Driver driver) {
079            this.driver = driver;
080        }
081
082        @Override
083        public int handleExecutionException(
084                final Exception ex,
085                final CommandLine commandLine,
086                final CommandLine.ParseResult parseResult) {
087            commandLine.getErr().println(ex.getMessage());
088            ex.printStackTrace(commandLine.getErr());
089            commandLine.usage(commandLine.getErr());
090            return commandLine.getCommandSpec().exitCodeOnExecutionException();
091        }
092    }
093
094}