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

au.net.causal.maven.plugins.boxdb.AbstractDatabaseMojo 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.BoxConfiguration;
import au.net.causal.maven.plugins.boxdb.db.BoxContext;
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.BoxDatabaseFactory;
import au.net.causal.maven.plugins.boxdb.db.BoxLookup;
import au.net.causal.maven.plugins.boxdb.db.DatabaseStage;
import au.net.causal.maven.plugins.boxdb.db.DockerService;
import au.net.causal.maven.plugins.boxdb.db.ExecutionMode;
import au.net.causal.maven.plugins.boxdb.db.ProjectConfiguration;
import au.net.causal.maven.plugins.boxdb.db.ImageUpdateMode;
import au.net.causal.maven.plugins.boxdb.db.ScriptExecution;
import au.net.causal.maven.plugins.boxdb.db.ScriptSelection;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.shared.filtering.MavenReaderFilter;
import org.apache.maven.shared.filtering.MavenResourcesFiltering;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.repository.RemoteRepository;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

public abstract class AbstractDatabaseMojo extends AbstractDockerDbMojo
{
    @Parameter(property = "db.type")
    private String databaseType;

    @Parameter(property = "db.version")
    private String databaseVersion;

    @Parameter(property = "db.name")
    private String databaseName;

    @Parameter(property = "db.containerName")
    private String containerName;

	@Parameter(property = "db.file")
	private File databaseFile;

    @Parameter(property = "db.restoreFile")
    private File databaseRestoreFile;

    @Parameter(property = "db.user")
    private String databaseUser;

    @Parameter(property = "db.password")
    private String databasePassword;

    @Parameter
    private Map databaseConfiguration = new LinkedHashMap<>();

    /**
     * Only used to allow databaseConfiguration parameter to be set from the command line.  In plugin
     * configurations, only databaseConfiguration should be used.
     */
    @Parameter(property = "db.configuration")
    private List databaseConfigurationList = new ArrayList<>();

    @Parameter(property = "db.initialize")
    private Boolean databaseInitialize;

    @Parameter(property = "boxdb.imageUpdateMode", defaultValue = "ON", required = true)
    private ImageUpdateMode imageUpdateMode;

    /**
     * Maximum time to wait in seconds for database to start up.
     */
    @Parameter(property = "boxdb.startupTimeout", defaultValue = "60", required = true)
    protected long startupTimeout;

    /**
     * Maximum time in seconds a SQL script may run before it is terminated.  Timeouts may not have effect on all database types.
     */
    @Parameter(property = "boxdb.scriptTimeout", defaultValue = "3600", required = true)
    protected long scriptTimeout;

    /**
     * Maximum time in seconds a database backup or restore may run before it is terminated.  Timeouts may not have effect
     * on all database types.
     */
    @Parameter(property = "boxdb.backupTimeout", defaultValue = "3600", required = true)
    protected long backupTimeout;

    /**
     * If true, passwords for connections are displayed in console output.  If false (the default), they are not.
     */
    @Parameter(property = "boxdb.displayPasswords", defaultValue = "false")
    protected boolean displayPasswords;

    @Parameter(defaultValue = "${project.build.directory}/boxdb", required = true)
    protected File workDirectory;

    @Parameter(defaultValue = "${user.home}/.boxdb", required = true)
    protected File globalConfigDirectory;

    @Parameter
    protected BoxConfiguration box = new BoxConfiguration();

    @Parameter(defaultValue = ScriptExecution.DEFAULT_BASE_DIRECTORY)
    private File defaultScriptDirectory;

    @Parameter(property = "db.deleteOnStop")
    protected boolean deleteOnStop;

    @Component
    protected MavenResourcesFiltering resourcesFiltering;

    @Component
    protected MavenReaderFilter readerFilter;

    @Component
    protected RepositorySystem repositorySystem;

    @Component
    protected ArchiverManager archiverManager;

    @Parameter(defaultValue = "${repositorySystemSession}", readonly = true)
    protected RepositorySystemSession repoSession;

    @Parameter(defaultValue = "${project.remotePluginRepositories}", readonly = true)
    protected List remoteRepos;

    protected final List tempFilesCreated = new ArrayList<>();

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException
    {
        //If we don't have a real project then use tempdir as work directory
        boolean usingTempDirectory = false;
        if (project == null || project.getFile() == null)
        {
            //Can't do this - to map scripts to docker machine they need to be inside user dir on Mac
            //workDirectory = new File(System.getProperty("java.io.tmpdir"));
            workDirectory = new File(".").getAbsoluteFile();
            usingTempDirectory = true;
        }

        if (databaseType != null)
            box.setDatabaseType(databaseType);
        if (databaseVersion != null)
            box.setDatabaseVersion(databaseVersion);
        if (containerName != null)
            box.setContainerName(containerName);
        if (databaseName != null)
            box.setDatabaseName(databaseName);
	    if (databaseFile != null)
	    	box.setDatabaseFile(databaseFile.toPath());
        if (databaseRestoreFile != null)
            box.setRestoreFile(databaseRestoreFile);
        if (databaseUser != null)
            box.setDatabaseUser(databaseUser);
        if (databasePassword != null)
            box.setDatabasePassword(databasePassword);

        if (settings.isOffline())
            imageUpdateMode = ImageUpdateMode.OFF;

        if (!databaseConfigurationList.isEmpty())
            fillInMapFromListParameter(databaseConfiguration, databaseConfigurationList);
        if (!databaseConfiguration.isEmpty())
            box.getConfiguration().putAll(databaseConfiguration);

        if (databaseInitialize != null)
            box.setInitializeDatabase(databaseInitialize);

        //Fill in box default scripts if needed
        if (box.getScriptExecutions().isEmpty())
            box.setScriptExecutions(defaultScriptExecutions());

        try
        {
            super.execute();
        }
        finally
        {
            //If we don't have a project we have used the user's temp directory
            //so try and clean this up after execution
            if (usingTempDirectory)
            {
                //Delete in reverse order, so we get directories last
                Collections.reverse(tempFilesCreated);
                for (Path tempFile : tempFilesCreated)
                {
                    try
                    {
                        getLog().info("Delete temp file " + tempFile);
                        Files.delete(tempFile);
                    }
                    catch (IOException e)
                    {
                        getLog().warn("Error deleting temp file " + tempFile);
                    }
                }
            }
        }
    }

    private void fillInMapFromListParameter(Map map, List list)
    {
        for (String item : list)
        {
            String[] kv = item.split(Pattern.quote("="), 2);
            if (kv.length == 2)
                map.put(kv[0], kv[1]);
        }
    }

    private List defaultScriptExecutions()
    {
        ScriptExecution createExecution = new ScriptExecution();
        createExecution.setDirectory(defaultScriptDirectory);
        createExecution.setIgnoreMissing(true);
        createExecution.setSelection(ScriptSelection.FIRST);
        createExecution.setStage(DatabaseStage.CREATE);
        createExecution.setMode(ExecutionMode.NATIVE);
        createExecution.getScripts().add("create-${box.databaseType}-${box.databaseVersion}.sql");
        createExecution.getScripts().add("create-${box.databaseType}.sql");
        createExecution.getScripts().add("create.sql");

        ScriptExecution createJdbcExecution = new ScriptExecution();
        createJdbcExecution.setDirectory(defaultScriptDirectory);
        createJdbcExecution.setIgnoreMissing(true);
        createJdbcExecution.setSelection(ScriptSelection.FIRST);
        createJdbcExecution.setStage(DatabaseStage.CREATE);
        createJdbcExecution.setMode(ExecutionMode.JDBC);
        createJdbcExecution.getScripts().add("create-jdbc-${box.databaseType}-${box.databaseVersion}.sql");
        createJdbcExecution.getScripts().add("create-jdbc-${box.databaseType}.sql");
        createJdbcExecution.getScripts().add("create-jdbc.sql");

        ScriptExecution setupExecution = new ScriptExecution();
        setupExecution.setDirectory(defaultScriptDirectory);
        setupExecution.setIgnoreMissing(true);
        setupExecution.setSelection(ScriptSelection.FIRST);
        setupExecution.setStage(DatabaseStage.SETUP);
        setupExecution.setMode(ExecutionMode.NATIVE);
        setupExecution.getScripts().add("setup-${box.databaseType}-${box.databaseVersion}.sql");
        setupExecution.getScripts().add("setup-${box.databaseType}.sql");
        setupExecution.getScripts().add("setup.sql");

        ScriptExecution setupJdbcExecution = new ScriptExecution();
        setupJdbcExecution.setDirectory(defaultScriptDirectory);
        setupJdbcExecution.setIgnoreMissing(true);
        setupJdbcExecution.setSelection(ScriptSelection.FIRST);
        setupJdbcExecution.setStage(DatabaseStage.SETUP);
        setupJdbcExecution.setMode(ExecutionMode.JDBC);
        setupJdbcExecution.getScripts().add("setup-jdbc-${box.databaseType}-${box.databaseVersion}.sql");
        setupJdbcExecution.getScripts().add("setup-jdbc-${box.databaseType}.sql");
        setupJdbcExecution.getScripts().add("setup-jdbc.sql");

        ScriptExecution postRestoreExecution = new ScriptExecution();
        postRestoreExecution.setDirectory(defaultScriptDirectory);
        postRestoreExecution.setIgnoreMissing(true);
        postRestoreExecution.setSelection(ScriptSelection.FIRST);
        postRestoreExecution.setStage(DatabaseStage.POST_RESTORE);
        postRestoreExecution.setMode(ExecutionMode.NATIVE);
        postRestoreExecution.getScripts().add("postrestore-${box.databaseType}-${box.databaseVersion}.sql");
        postRestoreExecution.getScripts().add("postrestore-${box.databaseType}.sql");
        postRestoreExecution.getScripts().add("postrestore.sql");

        ScriptExecution postRestoreJdbcExecution = new ScriptExecution();
        postRestoreJdbcExecution.setDirectory(defaultScriptDirectory);
        postRestoreJdbcExecution.setIgnoreMissing(true);
        postRestoreJdbcExecution.setSelection(ScriptSelection.FIRST);
        postRestoreJdbcExecution.setStage(DatabaseStage.POST_RESTORE);
        postRestoreJdbcExecution.setMode(ExecutionMode.JDBC);
        postRestoreJdbcExecution.getScripts().add("postrestore-jdbc-${box.databaseType}-${box.databaseVersion}.sql");
        postRestoreJdbcExecution.getScripts().add("postrestore-jdbc-${box.databaseType}.sql");
        postRestoreJdbcExecution.getScripts().add("postrestore-jdbc.sql");

        return Arrays.asList(createExecution, createJdbcExecution,
                             setupExecution, setupJdbcExecution,
                             postRestoreExecution, postRestoreJdbcExecution);
    }

    protected ImageUpdateMode getImageUpdateMode()
    {
        return imageUpdateMode;
    }

    protected BoxDatabaseFactory databaseFactory(ExceptionalSupplier serviceHub)
    throws MojoExecutionException, BoxDatabaseException
    {
	    String dbType = box.getDatabaseType();
	    BoxLookup lookup = new BoxLookup(getLog(), AbstractDatabaseMojo.class.getClassLoader());
	    BoxDatabaseFactory factory = lookup.findFactory(dbType);
	    if (factory == null)
	    {
		    throw new MojoExecutionException("Database type '" + dbType + "' not supported.  Available database types: " +
				    lookup.getAvailableBoxFactoryNames());
	    }

	    return factory;
    }

    protected BoxDatabase database(ExceptionalSupplier serviceHub)
    throws MojoExecutionException, BoxDatabaseException
    {
        BoxDatabaseFactory factory = databaseFactory(serviceHub);
        BoxContext context = new BoxContext(serviceHub, authConfigFactory, workDirectory.toPath(), globalConfigDirectory.toPath(),
                                    getImageUpdateMode(), getLog(), logSpecFactory, session, resourcesFiltering,
                                    readerFilter, repositorySystem, repoSession, remoteRepos, archiverManager);
        ProjectConfiguration projectConfiguration = new ProjectConfiguration(project, settings, Duration.ofSeconds(scriptTimeout), Duration.ofSeconds(backupTimeout));

        return factory.create(box, projectConfiguration, context);
    }

	protected void stopDatabaseContainer(BoxDatabase boxDatabase)
	throws MojoExecutionException, BoxDatabaseException
	{
		boolean exists = true;
		if (!boxDatabase.exists())
		{
			getLog().warn("Database '" + boxDatabase.getName() + "' does not exist");
			exists = false;
		}
		else if (!boxDatabase.isRunning())
			getLog().info("Database '" + boxDatabase.getName() + "' is not running");
		else
		{
			getLog().info("Stopping database '" + boxDatabase.getName() + "'");
			boxDatabase.stop();
			getLog().info("Database stopped.");
		}

		if (exists && deleteOnStop)
		{
			getLog().info("Deleting database '" + boxDatabase.getName() + "'");
			boxDatabase.delete();
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy