Skip to content

Commit

Permalink
[54] Refactor the ServerManager.start() methods and configuration.
Browse files Browse the repository at this point in the history
Signed-off-by: James R. Perkins <jperkins@redhat.com>
  • Loading branch information
jamezp committed Jul 19, 2024
1 parent 3e8bf10 commit 98ea195
Show file tree
Hide file tree
Showing 7 changed files with 356 additions and 92 deletions.
11 changes: 2 additions & 9 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,8 @@ and `org.wildfly.plugin.tools.server.StandaloneManager` utilities to interact wi

[source,java]
----
final Path wildflyHome = Paths.get(System.getProperty("user.home"), "servers", "wildfly-10.0.0.Final");
final Process process = Launcher.of(StandaloneCommandBuilder.of(wildflyHome)).launch();
try (final ModelControllerClient client = ModelControllerClient.Factory.create(InetAddress.getLocalHost(), 9990)) {
final StandaloneManager serverManager = ServerManager.builder().client(client).process(process).standalone();
final Path wildflyHome = Paths.get(System.getProperty("user.home"), "servers", "wildfly-33.0.0.Final");
try (StandaloneManager serverManager = ServerManager.start(Configuration.create(StandaloneCommandBuilder.of(wildflyHome)))) {
// Wait at the maximum 30 seconds for the server to start
if (!serverManager.waitFor(30, TimeUnit.SECONDS)) {
throw new RuntimeException("Server did not start within 30 seconds.");
Expand All @@ -102,10 +100,5 @@ try (final ModelControllerClient client = ModelControllerClient.Factory.create(I
final DeploymentManager deploymentManager = serverManager.deploymentManager();
final Deployment deployment = Deployment.of(deploymentPath);
deploymentManager.forceDeploy(deployment).assertSuccess();
// Shutdown the standalone server
serverManager.shutdown();
} finally {
process.destroy();
}
----
285 changes: 274 additions & 11 deletions src/main/java/org/wildfly/plugin/tools/server/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,81 @@

package org.wildfly.plugin.tools.server;

import java.io.File;
import java.io.UncheckedIOException;
import java.lang.ProcessBuilder.Redirect;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.Map;

import org.jboss.as.controller.client.ModelControllerClient;
import org.wildfly.core.launcher.BootableJarCommandBuilder;
import org.wildfly.core.launcher.CommandBuilder;
import org.wildfly.core.launcher.DomainCommandBuilder;
import org.wildfly.core.launcher.Launcher;
import org.wildfly.core.launcher.StandaloneCommandBuilder;

/**
* The configuration used when starting a server.
*
* @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
*/
public class Configuration {
@SuppressWarnings({ "unused", "UnusedReturnValue" })
public abstract class Configuration<T extends Configuration<T>> {
protected enum LaunchType {
DOMAIN,
STANDALONE
}

private final CommandBuilder commandBuilder;
private final Map<String, String> env;
private boolean redirectErrorStream;
private Redirect outputDestination;
private Redirect errorDestination;
private File workingDirectory;
private ModelControllerClient client;
private String managementAddress;
private int managementPort;
private boolean shutdownOnClose;

public static Configuration create() {
return new Configuration();
protected Configuration(final CommandBuilder commandBuilder) {
this.commandBuilder = commandBuilder;
this.env = new LinkedHashMap<>();
}

/**
* Creates a standalone configuration to launch a standalone server.
*
* @param commandBuilder the standalone command builder used to launch the server
*
* @return a new standalone configuration
*/
public static StandaloneConfiguration create(final StandaloneCommandBuilder commandBuilder) {
return new StandaloneConfiguration(commandBuilder);
}

/**
* Creates a standalone configuration to launch a standalone server via the bootable JAR.
*
* @param commandBuilder the bootable JAR command builder used to launch the server
*
* @return a new standalone configuration
*/
public static StandaloneConfiguration create(final BootableJarCommandBuilder commandBuilder) {
return new StandaloneConfiguration(commandBuilder);
}

/**
* Creates a domain configuration to launch a domain server
*
* @param commandBuilder the domain command builder used to launch the server
*
* @return a new domain configuration
*/
public static DomainConfiguration create(final DomainCommandBuilder commandBuilder) {
return new DomainConfiguration(commandBuilder);
}

/**
Expand All @@ -35,9 +92,9 @@ public static Configuration create() {
*
* @return this configuration
*/
public Configuration client(final ModelControllerClient client) {
public T client(final ModelControllerClient client) {
this.client = client;
return this;
return self();
}

/**
Expand All @@ -64,9 +121,9 @@ protected ModelControllerClient client() {
*
* @return this configuration
*/
public Configuration managementAddress(final String managementAddress) {
public T managementAddress(final String managementAddress) {
this.managementAddress = managementAddress;
return this;
return self();
}

/**
Expand All @@ -86,9 +143,9 @@ protected String managementAddress() {
*
* @return this configuration
*/
public Configuration managementPort(final int managementPort) {
public T managementPort(final int managementPort) {
this.managementPort = managementPort;
return this;
return self();
}

/**
Expand All @@ -108,9 +165,9 @@ protected int managementPort() {
*
* @return this configuration
*/
public Configuration shutdownOnClose(final boolean shutdownOnClose) {
public T shutdownOnClose(final boolean shutdownOnClose) {
this.shutdownOnClose = shutdownOnClose;
return this;
return self();
}

/**
Expand All @@ -121,4 +178,210 @@ public Configuration shutdownOnClose(final boolean shutdownOnClose) {
protected boolean shutdownOnClose() {
return shutdownOnClose;
}

/**
* Set to {@code true} if the error stream should be redirected to the output stream.
*
* @param redirectErrorStream {@code true} to merge the error stream into the output stream, otherwise {@code false}
* to keep the streams separate
*
* @return the Configuration
*/
public T redirectErrorStream(final boolean redirectErrorStream) {
this.redirectErrorStream = redirectErrorStream;
return self();
}

/**
* Redirects the output of the process to a file.
*
* @param file the file to redirect the output to
*
* @return the Configuration
*
* @see Redirect#to(java.io.File)
*/
public T redirectOutput(final File file) {
outputDestination = Redirect.to(file);
return self();
}

/**
* Redirects the output of the process to a file.
*
* @param path the path to redirect the output to
*
* @return the Configuration
*
* @see Redirect#to(java.io.File)
*/
public T redirectOutput(final Path path) {
return redirectOutput(path.toFile());
}

/**
* Redirects the output of the process to the destination provided.
*
* @param destination the output destination
*
* @return the Configuration
*
* @see java.lang.ProcessBuilder#redirectOutput(Redirect)
*/
public T redirectOutput(final Redirect destination) {
outputDestination = destination;
return self();
}

/**
* Redirects the error stream of the process to a file.
*
* @param file the file to redirect the error stream to
*
* @return the Configuration
*
* @see Redirect#to(java.io.File)
*/
public T redirectError(final File file) {
errorDestination = Redirect.to(file);
return self();
}

/**
* Redirects the error stream of the process to the destination provided.
*
* @param destination the error stream destination
*
* @return the Configuration
*
* @see java.lang.ProcessBuilder#redirectError(Redirect)
*/
public T redirectError(final Redirect destination) {
errorDestination = destination;
return self();
}

/**
* Sets the working directory for the process created.
*
* @param path the path to the working directory
*
* @return the Configuration
*
* @see java.lang.ProcessBuilder#directory(java.io.File)
*/
public T directory(final Path path) {
workingDirectory = (path == null ? null : path.toAbsolutePath().normalize().toFile());
return self();
}

/**
* Sets the working directory for the process created.
*
* @param dir the working directory
*
* @return the Configuration
*
* @see java.lang.ProcessBuilder#directory(java.io.File)
*/
public T directory(final File dir) {
workingDirectory = dir;
return self();
}

/**
* Sets the working directory for the process created.
*
* @param dir the working directory
*
* @return the Configuration
*
* @see java.lang.ProcessBuilder#directory(java.io.File)
*/
public T directory(final String dir) {
if (dir == null)
return self();
Path path = Path.of(dir);
if (Files.notExists(path)) {
throw new IllegalArgumentException(String.format("Directory '%s' does not exist", dir));
}
if (!Files.isDirectory(path)) {
throw new IllegalArgumentException(String.format("Directory '%s' is not a directory.", dir));
}
return directory(path.toAbsolutePath().normalize());
}

/**
* Adds an environment variable to the process being created. If the key or value is {@code null}, the environment
* variable will not be added.
*
* @param key they key for the variable
* @param value the value for the variable
*
* @return the Configuration
*
* @see ProcessBuilder#environment()
*/
public T addEnvironmentVariable(final String key, final String value) {
if (key != null && value != null) {
env.put(key, value);
}
return self();
}

/**
* Adds the environment variables to the process being created. Note that {@code null} keys or values will not be
* added.
*
* @param env the environment variables to add
*
* @return the Configuration
*
* @see ProcessBuilder#environment()
*/
public T addEnvironmentVariables(final Map<String, String> env) {
env.forEach((key, value) -> {
if (key != null && value != null) {
addEnvironmentVariable(key, value);
}
});
return self();
}

/**
* The command builder used to create the launcher.
*
* @return the command builder
*/
protected CommandBuilder commandBuilder() {
return commandBuilder;
}

/**
* A configured launcher for create the server process.
*
* @return the configured launcher
*/
protected Launcher launcher() {
return Launcher.of(commandBuilder)
.addEnvironmentVariables(env)
.redirectError(errorDestination)
.redirectOutput(outputDestination)
.setDirectory(workingDirectory)
.setRedirectErrorStream(redirectErrorStream);
}

/**
* The type of the server to launch.
*
* @return the type of the server
*/
protected abstract LaunchType launchType();

/**
* This instance.
*
* @return this instance
*/
protected abstract T self();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/

package org.wildfly.plugin.tools.server;

import org.wildfly.core.launcher.CommandBuilder;

/**
* Represents the configuration used to boot a domain server.
*
* @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
*/
public class DomainConfiguration extends Configuration<DomainConfiguration> {
protected DomainConfiguration(final CommandBuilder commandBuilder) {
super(commandBuilder);
}

@Override
protected LaunchType launchType() {
return LaunchType.DOMAIN;
}

@Override
protected DomainConfiguration self() {
return this;
}
}
Loading

0 comments on commit 98ea195

Please sign in to comment.