org.wildfly.plugin.server.AbstractStartMojo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of wildfly-maven-plugin Show documentation
Show all versions of wildfly-maven-plugin Show documentation
A maven plugin that allows various management operations to be executed on WildFly Application
Server.
The newest version!
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/
package org.wildfly.plugin.server;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.repository.RemoteRepository;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.client.helpers.ClientConstants;
import org.jboss.as.controller.client.helpers.Operations;
import org.jboss.galleon.maven.plugin.util.MavenArtifactRepositoryManager;
import org.jboss.galleon.universe.maven.repo.MavenRepoManager;
import org.wildfly.core.launcher.CommandBuilder;
import org.wildfly.core.launcher.Launcher;
import org.wildfly.plugin.common.AbstractServerConnection;
import org.wildfly.plugin.common.PropertyNames;
import org.wildfly.plugin.common.StandardOutput;
import org.wildfly.plugin.core.MavenRepositoriesEnricher;
import org.wildfly.plugin.tools.server.ServerManager;
/**
* @author James R. Perkins
*/
public abstract class AbstractStartMojo extends AbstractServerConnection {
@Component
protected RepositorySystem repoSystem;
@Parameter(defaultValue = "${repositorySystemSession}", readonly = true, required = true)
protected RepositorySystemSession session;
@Parameter(defaultValue = "${project.remoteProjectRepositories}", readonly = true, required = true)
protected List repositories;
@Parameter(defaultValue = "${project}", readonly = true, required = true)
protected MavenProject project;
@Parameter(defaultValue = "${session}", readonly = true, required = true)
protected MavenSession mavenSession;
/**
* The JVM options to use.
*/
@Parameter(alias = "java-opts", property = PropertyNames.JAVA_OPTS)
protected String[] javaOpts;
/**
* The {@code JAVA_HOME} to use for launching the server.
*/
@Parameter(alias = "java-home", property = PropertyNames.JAVA_HOME)
protected String javaHome;
/**
* Starts the server with debugging enabled.
*/
@Parameter(property = "wildfly.debug", defaultValue = "false")
protected boolean debug;
/**
* Sets the hostname to listen on for debugging. An {@code *} means all hosts.
*/
@Parameter(property = "wildfly.debug.host", defaultValue = "*")
protected String debugHost;
/**
* Sets the port the debugger should listen on.
*/
@Parameter(property = "wildfly.debug.port", defaultValue = "8787")
protected int debugPort;
/**
* Indicates whether the server should suspend itself until a debugger is attached.
*/
@Parameter(property = "wildfly.debug.suspend", defaultValue = "false")
protected boolean debugSuspend;
/**
* The path to the system properties file to load.
*/
@Parameter(alias = "properties-file", property = PropertyNames.PROPERTIES_FILE)
protected String propertiesFile;
/**
* The timeout value to use when starting the server.
*/
@Parameter(alias = "startup-timeout", defaultValue = "60", property = PropertyNames.STARTUP_TIMEOUT)
private long startupTimeout;
/**
* The arguments to be passed to the server.
*/
@Parameter(alias = "server-args", property = PropertyNames.SERVER_ARGS)
protected String[] serverArgs;
/**
* Set to {@code true} if you want to skip this goal, otherwise {@code false}.
*/
@Parameter(defaultValue = "false", property = PropertyNames.SKIP)
protected boolean skip;
/**
* Specifies the environment variables to be passed to the process being started.
*
*
*
* <env>
* <HOME>/home/wildfly/</HOME>
* </env>
*
*
*
*/
@Parameter
private Map env;
private final AtomicBoolean initialized = new AtomicBoolean();
protected ServerManager serverManager;
protected MavenRepoManager mavenRepoManager;
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 = createMavenRepoManager();
}
}
protected MavenRepoManager createMavenRepoManager() throws MojoExecutionException {
return new MavenArtifactRepositoryManager(repoSystem, session, repositories);
}
protected abstract Path getServerHome() throws MojoExecutionException, MojoFailureException;
protected ServerContext startServer(final ServerType serverType) throws MojoExecutionException, MojoFailureException {
final Log log = getLog();
init();
Path server = getServerHome();
// Determine how stdout should be consumed
try {
final StandardOutput out = standardOutput();
// Create the server and close the client after the start. The process will continue running even after
// the maven process may have been finished
final ModelControllerClient client = createClient();
if (ServerManager.isRunning(client)) {
throw new MojoExecutionException(String.format("%s server is already running?", serverType));
}
final CommandBuilder commandBuilder = createCommandBuilder(server);
log.info(String.format("%s server is starting up.", serverType));
final Launcher launcher = Launcher.of(commandBuilder)
.setRedirectErrorStream(true);
if (env != null) {
for (Map.Entry entry : env.entrySet()) {
if (entry.getKey() != null && entry.getValue() != null) {
launcher.addEnvironmentVariable(entry.getKey(), entry.getValue());
}
}
}
out.getRedirect().ifPresent(launcher::redirectOutput);
final Process process = launcher.launch();
if (serverType == ServerType.DOMAIN) {
serverManager = ServerManager.builder().process(process).client(client).domain();
} else {
serverManager = ServerManager.builder().process(process).client(client).standalone();
}
// Note that if this thread is started and no shutdown goal is executed this stop the stdout and stderr
// from being logged any longer. The user was warned in the documentation.
out.startConsumer(process);
if (!serverManager.waitFor(startupTimeout, TimeUnit.SECONDS)) {
throw new MojoExecutionException(String.format("Server failed to start in %s seconds.", startupTimeout));
}
if (!process.isAlive()) {
throw new MojoExecutionException("The process has been terminated before the start goal has completed.");
}
return new ServerContext() {
@Override
public Process process() {
return process;
}
@Override
public CommandBuilder commandBuilder() {
return commandBuilder;
}
@Override
public Path jbossHome() {
return server;
}
};
} catch (MojoExecutionException e) {
throw e;
} catch (Exception e) {
throw new MojoExecutionException("The server failed to start", e);
}
}
protected abstract CommandBuilder createCommandBuilder(final Path jbossHome) throws MojoExecutionException;
protected StandardOutput standardOutput() throws IOException {
return StandardOutput.parse(null, false);
}
/**
* Allows the {@link #javaOpts} to be set as a string. The string is assumed to be space delimited.
*
* @param value a spaced delimited value of JVM options
*/
@SuppressWarnings("unused")
public void setJavaOpts(final String value) {
if (value != null) {
javaOpts = value.split("\\s+");
}
}
/**
* Checks the current state of the server. If the server is in a state of
* {@link ClientConstants#CONTROLLER_PROCESS_STATE_RESTART_REQUIRED}, the process is restarted and a new
* {@link ServerContext} is returned. If the server is in a stat of
* {@link ClientConstants#CONTROLLER_PROCESS_STATE_RELOAD_REQUIRED}, the server will be reloaded and wait until
* the server is running. If the server is in any other state, other than
* {@link ClientConstants#CONTROLLER_PROCESS_STATE_RUNNING}, a warning message is logged to let the user know
* the state is unknown.
*
* @param client the client used to communicate with the server
* @param context the current server context
* @return a new context if a restart was required, otherwise the same context
* @throws IOException if an error occurs communicating with the server
* @throws MojoExecutionException if a failure occurs checking the state or reloading the server
* @throws MojoFailureException if a failure occurs checking the state or reloading the server
*/
protected ServerContext actOnServerState(final ModelControllerClient client, final ServerContext context)
throws IOException, MojoExecutionException, MojoFailureException {
final String serverState = serverManager.serverState();
if (ClientConstants.CONTROLLER_PROCESS_STATE_RESTART_REQUIRED.equals(serverState)) {
// Shutdown the server
serverManager.shutdown(timeout);
// Restart the server process
return startServer(ServerType.STANDALONE);
} else if (ClientConstants.CONTROLLER_PROCESS_STATE_RELOAD_REQUIRED.equals(serverState)) {
serverManager.executeReload(Operations.createOperation("reload"));
try {
if (!serverManager.waitFor(startupTimeout, TimeUnit.SECONDS)) {
throw new MojoExecutionException(String.format("Server failed to start in %s seconds.", startupTimeout));
}
} catch (InterruptedException e) {
throw new MojoExecutionException("Failed to wait for standalone server after a reload.", e);
}
} else if (!ClientConstants.CONTROLLER_PROCESS_STATE_RUNNING.equals(serverState)) {
getLog().warn(String.format(
"The server may be in an unexpected state for further interaction. The current state is %s", serverState));
}
return context;
}
@Override
protected int getManagementPort() {
// Check the java-opts for a management port override
if (javaOpts != null) {
for (String opt : javaOpts) {
if (opt.startsWith("-Djboss.management.http.port=") || opt.startsWith("-Djboss.management.https.port=")) {
final int equals = opt.indexOf('=');
return Integer.parseInt(opt.substring(equals + 1).trim());
}
if (opt.startsWith("-Djboss.socket.binding.port-offset=")) {
final int equals = opt.indexOf('=');
return super.getManagementPort() + Integer.parseInt(opt.substring(equals + 1).trim());
}
}
}
return super.getManagementPort();
}
@Override
protected String getManagementHostName() {
// Check the java-opts for a management port override
if (javaOpts != null) {
for (String opt : javaOpts) {
if (opt.startsWith("-Djboss.bind.address.management=")) {
final int equals = opt.indexOf('=');
return opt.substring(equals + 1).trim();
}
}
}
return super.getManagementHostName();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy