All Downloads are FREE. Search and download functionalities are using the official Maven repository.

au.net.causal.maven.plugins.boxdb.StartAndWaitMojo Maven / Gradle / Ivy

There is a newer version: 3.3
Show newest version
package au.net.causal.maven.plugins.boxdb;

import au.net.causal.maven.plugins.boxdb.db.BoxDatabase;
import au.net.causal.maven.plugins.boxdb.db.BoxDatabaseException;
import au.net.causal.maven.plugins.boxdb.db.DatabaseTarget;
import au.net.causal.maven.plugins.boxdb.db.DockerService;
import au.net.causal.maven.plugins.boxdb.db.JdbcConnectionInfo;
import io.fabric8.maven.docker.access.DockerAccessException;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;

import java.util.concurrent.TimeUnit;

/**
 * Starts the database and waits until termination with control+c.  Shuts down cleanly in shutdown hook.
 */
@Mojo(name="startwait", requiresProject = false)
public class StartAndWaitMojo extends StartMojo
{
    protected void registerHookAndStartDatabase(ExceptionalSupplier dockerService)
    throws MojoExecutionException, DockerAccessException
    {
	    try
	    {
	        BoxDatabase box = database(dockerService);

            try
            {
                super.executeInternal(dockerService);

                //Print some information for user to use the database
                JdbcConnectionInfo jdbcInfo = box.jdbcConnectionInfo(DatabaseTarget.USER);
                getLog().info("Database is set up and running:");
                getLog().info("    JDBC URL: " + jdbcInfo.getUri());
                if (jdbcInfo.getUser() != null)
                    getLog().info("    User: " + jdbcInfo.getUser());
                if (displayPasswords && jdbcInfo.getPassword() != null)
                    getLog().info("    Password: " + jdbcInfo.getPassword());
                getLog().info("    Database host: " + jdbcInfo.getHost());
                getLog().info("    Database port: " + jdbcInfo.getPort());
            }
            catch (Throwable t)
            {
                //If something goes wrong, run the shutdown stuff immediately instead of in a shutdown hook
                //I know there are classloader issues when running from hooks with Maven plugins
                //(see https://issues.apache.org/jira/browse/MNG-5589) but we do it anyway and it's more likely
                //more classes need loading if an error occurs early than if everything runs smoothly
                try
                {
                    if (shouldStopContainer())
                        stopDatabaseContainer(box);
                }
                catch (Throwable stopError)
                {
                    t.addSuppressed(stopError);
                }

                throw t;
            }

            //If we get here nothing went wrong starting the DB so register the shutdown hook now
            //This shutdown hook runs when control+c is pressed and cleanly shuts down the database
            //There are known problems with shutdown hooks and Maven plugins
            //(see https://issues.apache.org/jira/browse/MNG-5589)
            //but we'll do it anyway for now - it's only a convenience for users to stop with control+c
            Thread stopperThread = new Thread(new Stopper(box), "boxdb-shutdown-hook-thread");
            Runtime.getRuntime().addShutdownHook(stopperThread);
        }
        catch (BoxDatabaseException e)
        {
            throw new MojoExecutionException("Error setting up database: " + e, e);
        }
    }

    /**
     * @return true if the container should be stopped on error or on control+c, false if not.
     */
    protected boolean shouldStopContainer()
    {
        return true;
    }

    protected void waitForControlC()
    {
        //Now that everything is set up, block until control+c is pressed
        getLog().info(getWaitMessage());
        try
        {
            while (true)
            {
                Thread.sleep(TimeUnit.DAYS.toMillis(10000L));
            }
        }
        catch (InterruptedException e)
        {
            getLog().info("Interrupted waiting.", e);
        }
    }

    @Override
    protected void executeInternal(ExceptionalSupplier dockerService)
    throws DockerAccessException, MojoExecutionException
    {
        registerHookAndStartDatabase(dockerService);
        waitForControlC();
    }

    protected String getWaitMessage()
    {
        return "Press control+c to stop the database container...";
    }

    private class Stopper implements Runnable
    {
        private final BoxDatabase database;

        public Stopper(BoxDatabase database)
        {
            this.database = database;
        }

        @Override
        public void run()
        {
            try
            {
                if (shouldStopContainer())
                    stopDatabaseContainer(database);
            }
            catch (BoxDatabaseException | MojoExecutionException e)
            {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy