au.net.causal.maven.plugins.boxdb.StartAndWaitMojo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of boxdb-maven-plugin Show documentation
Show all versions of boxdb-maven-plugin Show documentation
Maven plugin to start databases using Docker and VMs
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);
}
}
}
}