Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WFMP-206] Add ability to define provisioning details for the dev goal. #337

Merged
merged 1 commit into from
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions plugin/src/main/java/org/wildfly/plugin/dev/DevMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.ClosedWatchServiceException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
Expand All @@ -45,6 +46,7 @@
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.DosFileAttributes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand All @@ -70,7 +72,14 @@
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.galleon.ProvisioningException;
import org.jboss.galleon.ProvisioningManager;
import org.jboss.galleon.config.ProvisioningConfig;
import org.jboss.galleon.maven.plugin.util.MavenArtifactRepositoryManager;
import org.jboss.galleon.maven.plugin.util.MvnMessageWriter;
import org.jboss.galleon.universe.maven.repo.MavenRepoManager;
import org.twdata.maven.mojoexecutor.MojoExecutor;
import org.wildfly.channel.UnresolvedMavenArtifactException;
import org.wildfly.core.launcher.CommandBuilder;
import org.wildfly.plugin.cli.CommandConfiguration;
import org.wildfly.plugin.cli.CommandExecutor;
Expand All @@ -81,9 +90,14 @@
import org.wildfly.plugin.core.Deployment;
import org.wildfly.plugin.core.DeploymentManager;
import org.wildfly.plugin.core.DeploymentResult;
import org.wildfly.plugin.core.FeaturePack;
import org.wildfly.plugin.core.GalleonUtils;
import org.wildfly.plugin.core.PluginProgressTracker;
import org.wildfly.plugin.core.ServerHelper;
import org.wildfly.plugin.core.UndeployDescription;
import org.wildfly.plugin.deployment.PackageType;
import org.wildfly.plugin.provision.ChannelConfiguration;
import org.wildfly.plugin.provision.ChannelMavenArtifactRepositoryManager;
import org.wildfly.plugin.server.AbstractServerStartMojo;
import org.wildfly.plugin.server.ServerContext;
import org.wildfly.plugin.server.ServerType;
Expand Down Expand Up @@ -268,6 +282,66 @@ public class DevMojo extends AbstractServerStartMojo {
@Parameter(property = "wildfly.dev.remote", defaultValue = "false")
private boolean remote;

/**
* Arbitrary Galleon options used when provisioning the server. In case you
* are building a large amount of server in the same maven session, it
* is strongly advised to set 'jboss-fork-embedded' option to 'true' in
* order to fork Galleon provisioning and CLI scripts execution in dedicated
* processes. For example:
*
* <pre>
* &lt;galleon-options&gt;
* &lt;jboss-fork-embedded&gt;true&lt;/jboss-fork-embedded&gt;
* &lt;/galleon-options&gt;
* </pre>
*/
@Parameter(alias = "galleon-options")
private Map<String, String> galleonOptions = Collections.emptyMap();

/**
* Whether to use offline mode when the plugin resolves an artifact. In
* offline mode the plugin will only use the local Maven repository for an
* artifact resolution.
*/
@Parameter(alias = "offline-provisioning", defaultValue = "false", property = PropertyNames.WILDFLY_PROVISIONING_OFFLINE)
private boolean offlineProvisioning;

/**
* Set to {@code true} if you want to delete the existing server referenced from the {@code provisioningDir} and provision a
* new one,
* otherwise {@code false}.
*/
@Parameter(alias = "overwrite-provisioned-server", defaultValue = "false", property = PropertyNames.WILDFLY_PROVISIONING_OVERWRITE_PROVISIONED_SERVER)
private boolean overwriteProvisionedServer;

/**
* A list of feature-pack configurations to install, can be combined with layers. Use the System property
* {@code wildfly.provisioning.feature-packs} to provide a comma separated list of feature-packs.
*/
@Parameter(alias = "feature-packs", property = PropertyNames.WILDFLY_PROVISIONING_FEATURE_PACKS)
private List<FeaturePack> featurePacks = Collections.emptyList();

/**
* A list of Galleon layers to provision. Can be used when feature-pack-location or feature-packs are set.
* Use the System property {@code wildfly.provisioning.layers} to provide a comma separated list of layers.
*/
@Parameter(alias = "layers", property = PropertyNames.WILDFLY_PROVISIONING_LAYERS)
private List<String> layers = Collections.emptyList();

/**
* A list of Galleon layers to exclude. Can be used when feature-pack-location or feature-packs are set.
* Use the System property {@code wildfly.provisioning.layers.excluded} to provide a comma separated list of layers to
* exclude.
*/
@Parameter(alias = "excluded-layers", property = PropertyNames.WILDFLY_PROVISIONING_LAYERS_EXCLUDED)
private List<String> excludedLayers = Collections.emptyList();

/**
* A list of channels used for resolving artifacts while provisioning.
*/
@Parameter(alias = "channels")
private List<ChannelConfiguration> channels;

// Lazily loaded list of patterns based on the ignorePatterns
private final List<Pattern> ignoreUpdatePatterns = new ArrayList<>();
// Lazy loaded
Expand Down Expand Up @@ -357,6 +431,22 @@ public String goal() {
return "dev";
}

@Override
protected MavenRepoManager createMavenRepoManager() throws MojoExecutionException {
if (channels == null) {
return offlineProvisioning ? new MavenArtifactRepositoryManager(repoSystem, session)
: new MavenArtifactRepositoryManager(repoSystem, session, repositories);
} else {
try {
return new ChannelMavenArtifactRepositoryManager(channels,
repoSystem, session, repositories,
getLog(), offlineProvisioning);
} catch (MalformedURLException | UnresolvedMavenArtifactException ex) {
throw new MojoExecutionException(ex.getLocalizedMessage(), ex);
}
}
}

@Override
protected CommandBuilder createCommandBuilder(final Path jbossHome) throws MojoExecutionException {
return createStandaloneCommandBuilder(jbossHome, serverConfig);
Expand All @@ -382,6 +472,39 @@ public void setIgnorePatterns(final String ignorePatterns) {
this.ignorePatterns = Utils.splitArguments(ignorePatterns);
}

@Override
protected Path provisionIfRequired(final Path installDir) throws MojoFailureException, MojoExecutionException {
if (!overwriteProvisionedServer && Files.exists(installDir)) {
getLog().info(String.format("A server already exists in %s, provisioning for %s:%s", installDir,
project.getGroupId(), project.getArtifactId()));
return installDir;
}
try (ProvisioningManager pm = ProvisioningManager.builder().addArtifactResolver(mavenRepoManager)
.setInstallationHome(installDir)
.setMessageWriter(new MvnMessageWriter(getLog()))
.build()) {
ProvisioningConfig config;
if (featurePacks.isEmpty()) {
return super.provisionIfRequired(installDir);
} else {
config = GalleonUtils.buildConfig(pm, featurePacks, layers, excludedLayers, galleonOptions,
serverConfig == null ? "standalone.xml" : serverConfig);
}
getLog().info("Provisioning server in " + installDir);
PluginProgressTracker.initTrackers(pm, getLog());
pm.provision(config);
// Check that at least the standalone or domain directories have been generated.
if (Files.notExists(installDir.resolve("standalone")) && Files.notExists(installDir.resolve("domain"))) {
getLog().error("Invalid galleon provisioning, no server provisioned in " + installDir + ". Make sure "
+ "that the list of Galleon feature-packs and Galleon layers are properly configured.");
throw new MojoExecutionException("Invalid plugin configuration, no server provisioned.");
}
} catch (ProvisioningException e) {
throw new MojoFailureException(e.getLocalizedMessage(), e);
}
return installDir;
}

private boolean registerDir(final WatchService watcher, final Path dir, final WatchHandler handler) throws IOException {
if (Files.exists(dir) && Files.isDirectory(dir)) {
final int currentSize = watchedDirectories.size();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public abstract class AbstractServerStartMojo extends AbstractServerConnection {
* The WildFly Application Server's home directory. If not used, WildFly will be downloaded.
*/
@Parameter(alias = "jboss-home", property = PropertyNames.JBOSS_HOME)
private String jbossHome;
protected String jbossHome;

/**
* The feature pack location. See the <a href="https://docs.wildfly.org/galleon/#_feature_pack_location">documentation</a>
Expand Down Expand Up @@ -213,10 +213,14 @@ protected void init() throws MojoExecutionException {
// Setting the mavenRepoManager is not thread-safe, however creating it more than once won't hurt anything
if (initialized.compareAndSet(false, true)) {
MavenRepositoriesEnricher.enrich(mavenSession, project, repositories);
mavenRepoManager = new MavenArtifactRepositoryManager(repoSystem, session, repositories);
mavenRepoManager = createMavenRepoManager();
}
}

protected MavenRepoManager createMavenRepoManager() throws MojoExecutionException {
return new MavenArtifactRepositoryManager(repoSystem, session, repositories);
}

protected ServerContext startServer(final ServerType serverType) throws MojoExecutionException, MojoFailureException {
final Log log = getLog();
init();
Expand Down Expand Up @@ -392,7 +396,7 @@ protected DomainCommandBuilder createDomainCommandBuilder(final Path jbossHome,
return commandBuilder;
}

private Path provisionIfRequired(final Path installDir) throws MojoFailureException {
protected Path provisionIfRequired(final Path installDir) throws MojoFailureException, MojoExecutionException {
if (jbossHome != null) {
// we do not need to download WildFly
return Paths.get(jbossHome);
Expand Down