au.net.causal.maven.plugins.boxdb.PrepareMojo Maven / Gradle / Ivy
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.DockerService;
import au.net.causal.maven.plugins.boxdb.db.ImageComponent;
import au.net.causal.maven.plugins.boxdb.db.ImageComponent.ImageStatus;
import io.fabric8.maven.docker.access.DockerAccessException;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Downloads any remote images, drivers and resources required to run a database, but does not actually run it.
* This goal can be used before going offline to ensure all remote resources required to run a database
* are present on the machine.
*
* @since 3.0
*/
@Mojo(name="prepare", requiresProject = false)
public class PrepareMojo extends AbstractDatabaseMojo
{
/**
* If true, remote repositories are checked if there are updates available for the current database even if the
* image already exists locally, and will fail the build if no remote image exists.
*
*
* This can be useful for checking for updates for database types that aren't using permanent version names, such as
* 'latest' with Docker images. It can also be useful for checking if a remote Docker image has disappeared.
*/
@Parameter(property = "boxdb.checkRemote")
private boolean checkRemote;
/**
* Generates a label for the currently configured database useful for logging.
*
* @return a human readable database label.
*/
protected String logLabelForDatabase()
{
return box.getDatabaseType() + ":" + box.getDatabaseVersion();
}
protected String logLabelForComponent(ImageComponent component)
{
return component.getName() + " (" + component.getType() + ")";
}
private String logLabelForComponents(Collection extends ImageComponent> components)
{
return components.stream()
.map(this::logLabelForComponent)
.collect(Collectors.joining(", "));
}
@Override
protected void executeInternal(ExceptionalSupplier dockerService)
throws DockerAccessException, MojoExecutionException
{
try
{
BoxDatabase boxDatabase = database(dockerService);
if (checkRemote)
{
Collection extends ImageComponent> imageComponents = boxDatabase.checkImage();
getLog().info("Prepare summary:");
for (ImageComponent imageComponent : imageComponents)
{
//Don't use logLabelForComponent() since we want the status printed as well
getLog().info(" * " + imageComponent.toString());
}
Set imageStatus = imageComponents.stream()
.map(ImageComponent::getStatus)
.collect(Collectors.toSet());
Map> imageComponentsByStatus =
imageComponents.stream()
.collect(Collectors.groupingBy(ImageComponent::getStatus));
if (imageStatus.contains(ImageStatus.LOCAL_ONLY))
{
throw new MojoExecutionException("Components for database " + logLabelForDatabase() +
" do not exist remotely, despite having a local image: " +
logLabelForComponents(imageComponentsByStatus.get(ImageStatus.LOCAL_ONLY)));
}
if (imageStatus.equals(EnumSet.of(ImageStatus.DOWNLOADED)))
{
getLog().info("Image for database " + logLabelForDatabase() + " already exists and is up to date.");
return;
}
if (imageStatus.contains(ImageStatus.NOT_DOWNLOADED))
{
getLog().info("Components to be downloaded: " +
logLabelForComponents(imageComponentsByStatus.get(ImageStatus.NOT_DOWNLOADED)));
}
if (imageStatus.contains(ImageStatus.REMOTE_UPDATE_AVAILABLE))
{
if (box.isUpdateImage())
{
getLog().info("Components to be updated: " +
logLabelForComponents(imageComponentsByStatus.get(ImageStatus.REMOTE_UPDATE_AVAILABLE)));
}
else
{
getLog().info("Components that have updates available: " +
logLabelForComponents(imageComponentsByStatus.get(ImageStatus.REMOTE_UPDATE_AVAILABLE)));
getLog().info("Image update mode is turned off, so they will not be updated. " +
"Configure imageUpdateMode in the box database configuration or use -Ddb.updateImage " +
"to update these components.");
}
}
boxDatabase.prepareImage();
getLog().info("Database prepare complete.");
}
else
{
//No need to check the remote or download updates if we already have local
if (boxDatabase.hasImage())
getLog().info("Image for database " + logLabelForDatabase() + " already exists.");
else
{
getLog().info("Image for database " + logLabelForDatabase() +
" does not exist locally. Downloading image...");
boxDatabase.prepareImage();
getLog().info("Database image downloaded.");
}
}
}
catch (BoxDatabaseException e)
{
throw new MojoExecutionException("Error preparing database: " + e, e);
}
}
}