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

org.wildfly.plugin.server.AbstractStartMojo Maven / Gradle / Ivy

Go to download

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