Skip to content

Commit

Permalink
[37] Implement AutoCloseable on the ServerManager. Use the process wh…
Browse files Browse the repository at this point in the history
…ere applicable in the server manager.

Signed-off-by: James R. Perkins <jperkins@redhat.com>
  • Loading branch information
jamezp committed Jun 27, 2024
1 parent 5ae85c3 commit d3e7e60
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 59 deletions.
8 changes: 6 additions & 2 deletions src/main/java/org/wildfly/plugin/tools/ServerHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* @see StandaloneManager
* @see DomainManager
*/
@SuppressWarnings("unused")
@SuppressWarnings({ "unused", "resource" })
@Deprecated(forRemoval = true, since = "1.1")
public class ServerHelper {

Expand Down Expand Up @@ -98,7 +98,11 @@ public static void reloadIfRequired(final ModelControllerClient client, final lo
* @param reloadOp the reload operation to execute
*/
public static void executeReload(final ModelControllerClient client, final ModelNode reloadOp) {
ServerManager.builder().client(client).standalone().executeReload(reloadOp);
try {
ServerManager.builder().client(client).standalone().executeReload(reloadOp);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.client.helpers.Operations;
Expand All @@ -25,15 +26,29 @@
* @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
*/
@SuppressWarnings("unused")
abstract class AbstractServerManager implements ServerManager {
abstract class AbstractServerManager<T extends ModelControllerClient> implements ServerManager {
private static final Logger LOGGER = Logger.getLogger(AbstractServerManager.class);
private static final ThreadLocal<Boolean> SKIP_STATE_CHECK = ThreadLocal.withInitial(() -> false);

protected final ProcessHandle process;
final T client;
private final boolean shutdownOnClose;
private final DeploymentManager deploymentManager;
private final AtomicBoolean closed;

protected AbstractServerManager(final ProcessHandle process, final ModelControllerClient client) {
protected AbstractServerManager(final ProcessHandle process, final T client,
final boolean shutdownOnClose) {
this.process = process;
this.client = client;
this.shutdownOnClose = shutdownOnClose;
deploymentManager = DeploymentManager.Factory.create(client);
this.closed = new AtomicBoolean(false);
}

@Override
public ModelControllerClient client() {
checkState();
return client;
}

@Override
Expand Down Expand Up @@ -109,14 +124,48 @@ public String takeSnapshot() throws IOException, OperationExecutionException {
* @throws OperationExecutionException if the reload operation fails
*/
@Override
public void executeReload(final ModelNode reloadOp) throws OperationExecutionException {
public void executeReload(final ModelNode reloadOp) throws IOException, OperationExecutionException {
try {
executeOperation(reloadOp);
} catch (IOException e) {
final Throwable cause = e.getCause();
if (!(cause instanceof ExecutionException) && !(cause instanceof CancellationException)) {
throw new RuntimeException(e);
throw e;
} // else ignore, this might happen if the channel gets closed before we got the response
}
}

@Override
public boolean isClosed() {
return closed.get();
}

@Override
public void close() {
if (closed.compareAndSet(false, true)) {
try {
SKIP_STATE_CHECK.set(true);
if (shutdownOnClose) {
try {
shutdown();
} catch (IOException e) {
LOGGER.error("Failed to shutdown the server while closing the server manager.", e);
}
}
try {
client.close();
} catch (IOException e) {
LOGGER.error("Failed to close the client.", e);
}
} finally {
SKIP_STATE_CHECK.remove();
}
}
}

void checkState() {
if (!SKIP_STATE_CHECK.get() && closed.get()) {
throw new IllegalStateException("The server manager has been closed and cannot process requests");
}
}
}
27 changes: 12 additions & 15 deletions src/main/java/org/wildfly/plugin/tools/server/DomainManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import java.util.Map;
import java.util.concurrent.TimeUnit;

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.as.controller.client.helpers.domain.DomainClient;
Expand All @@ -26,18 +25,12 @@
* @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
*/
@SuppressWarnings("unused")
public class DomainManager extends AbstractServerManager {
public class DomainManager extends AbstractServerManager<DomainClient> {
private static final Logger LOGGER = Logger.getLogger(DomainManager.class);
private final DomainClient client;

protected DomainManager(final ProcessHandle process, final DomainClient client) {
super(process, client);
this.client = client;
}

@Override
public ModelControllerClient client() {
return client;
DomainManager(final ProcessHandle process, final DomainClient client,
final boolean shutdownOnClose) {
super(process, client, shutdownOnClose);
}

@Override
Expand All @@ -62,7 +55,7 @@ public String serverState() {
* @throws OperationExecutionException if the operation used to determine the host name fails
*/
public ModelNode determineHostAddress() throws OperationExecutionException, IOException {
return CommonOperations.determineHostAddress(client);
return CommonOperations.determineHostAddress(client());
}

/**
Expand All @@ -73,7 +66,10 @@ public ModelNode determineHostAddress() throws OperationExecutionException, IOEx
*/
@Override
public boolean isRunning() {
return CommonOperations.isDomainRunning(client, false);
if (process != null) {
return process.isAlive() && CommonOperations.isDomainRunning(client(), false);
}
return CommonOperations.isDomainRunning(client(), false);
}

@Override
Expand Down Expand Up @@ -101,7 +97,8 @@ public void shutdown(final long timeout)
executeOperation(shutdownOp);
// Wait until the process has died
while (true) {
if (CommonOperations.isDomainRunning(client, true)) {
final boolean running = (process == null ? CommonOperations.isDomainRunning(client(), true) : process.isAlive());
if (running) {
Thread.onSpinWait();
} else {
break;
Expand All @@ -110,7 +107,7 @@ public void shutdown(final long timeout)
}

@Override
public void executeReload() {
public void executeReload() throws IOException, OperationExecutionException {
executeReload(Operations.createOperation("reload-servers"));
}

Expand Down
51 changes: 46 additions & 5 deletions src/main/java/org/wildfly/plugin/tools/server/ServerManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@

/**
* A simple manager for various interactions with a potentially running server.
* <p>
* When the server manager is closed, the underlying client is also closed.
* </p>
*
* @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
*/
@SuppressWarnings("unused")
public interface ServerManager {
public interface ServerManager extends AutoCloseable {

/**
* A builder used to build a {@link ServerManager}.
Expand All @@ -39,9 +42,13 @@ class Builder {
private String managementAddress;
private int managementPort;
private ProcessHandle process;
private boolean shutdownOnClose;

/**
* Sets the client to use for the server manager.
* <p>
* If the this server manager is {@linkplain #close() closed}, the client will also be closed.
* </p>
*
* @param client the client to use to communicate with the server
*
Expand Down Expand Up @@ -105,6 +112,19 @@ public Builder managementPort(final int managementPort) {
return this;
}

/**
* When set to {@code true} the server will be {@linkplain ServerManager#shutdown() shutdown} when the server
* manager is {@linkplain ServerManager#close() closed}.
*
* @param shutdownOnClose {@code true} to shutdown the server when the server manager is closed
*
* @return this builder
*/
public Builder shutdownOnClose(final boolean shutdownOnClose) {
this.shutdownOnClose = shutdownOnClose;
return this;
}

/**
* Creates a {@link StandaloneManager} based on the builders settings. If the
* {@link #client(ModelControllerClient) client} was not set, the {@link #managementAddress(String) managementAddress}
Expand All @@ -113,7 +133,7 @@ public Builder managementPort(final int managementPort) {
* @return a new {@link StandaloneManager}
*/
public StandaloneManager standalone() {
return new StandaloneManager(process, getOrCreateClient());
return new StandaloneManager(process, getOrCreateClient(), shutdownOnClose);
}

/**
Expand All @@ -124,7 +144,7 @@ public StandaloneManager standalone() {
* @return a new {@link DomainManager}
*/
public DomainManager domain() {
return new DomainManager(process, getOrCreateDomainClient());
return new DomainManager(process, getOrCreateDomainClient(), shutdownOnClose);
}

/**
Expand Down Expand Up @@ -153,9 +173,9 @@ public CompletableFuture<ServerManager> build() {
final String launchType = launchType(client).orElseThrow(() -> new IllegalStateException(
"Could not determine the type of the server. Verify the server is running."));
if ("STANDALONE".equals(launchType)) {
return new StandaloneManager(process, client);
return new StandaloneManager(process, client, shutdownOnClose);
} else if ("DOMAIN".equals(launchType)) {
return new DomainManager(process, getOrCreateDomainClient());
return new DomainManager(process, getOrCreateDomainClient(), shutdownOnClose);
}
throw new IllegalStateException(
String.format("Only standalone and domain servers are support. %s is not supported.", launchType));
Expand Down Expand Up @@ -475,4 +495,25 @@ default ModelNode executeOperation(final Operation op) throws IOException, Opera
}
throw new OperationExecutionException(op, result);
}

/**
* Checks if this server manager has been closed. The server manager may be closed if the underlying client was
* closed.
*
* @return {@code true} if the server manager was closed, otherwise {@code false}
* @since 1.2
*/
default boolean isClosed() {
throw new UnsupportedOperationException("Not yet implemented");
}

/**
* {@inheritDoc}
*
* @since 1.2
*/
@Override
default void close() {
throw new UnsupportedOperationException("Not yet implemented");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,12 @@
* @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a>
*/
@SuppressWarnings("unused")
public class StandaloneManager extends AbstractServerManager {
public class StandaloneManager extends AbstractServerManager<ModelControllerClient> {
private static final Logger LOGGER = Logger.getLogger(StandaloneManager.class);
private final ModelControllerClient client;

protected StandaloneManager(final ProcessHandle process, final ModelControllerClient client) {
super(process, client);
this.client = client;
}

@Override
public ModelControllerClient client() {
return client;
StandaloneManager(final ProcessHandle process, final ModelControllerClient client,
final boolean shutdownOnClose) {
super(process, client, shutdownOnClose);
}

@Override
Expand Down Expand Up @@ -81,7 +75,10 @@ public void reloadIfRequired(final long timeout, final TimeUnit unit) throws IOE

@Override
public boolean isRunning() {
return CommonOperations.isStandaloneRunning(client);
if (process != null) {
return process.isAlive() && CommonOperations.isStandaloneRunning(client());
}
return CommonOperations.isStandaloneRunning(client());
}

@Override
Expand All @@ -95,7 +92,8 @@ public void shutdown(final long timeout) throws IOException {
op.get("timeout").set(timeout);
executeOperation(op);
while (true) {
if (isRunning()) {
final boolean running = (process == null ? isRunning() : process.isAlive());
if (running) {
Thread.onSpinWait();
} else {
break;
Expand Down
14 changes: 14 additions & 0 deletions src/test/java/org/wildfly/plugin/tools/Environment.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@ public static ModelControllerClient createClient() throws UnknownHostException {
return ModelControllerClient.Factory.create(HOSTNAME, PORT);
}

/**
* Creates a {@link ServerManager.Builder} for testing with a default management address and port.
*
* @param process the process to bind to the server manager
*
* @return a server manager builder
*/
public static ServerManager.Builder createServerManagerBuilder(final Process process) {
return ServerManager.builder()
.managementAddress(HOSTNAME)
.managementPort(PORT)
.process(process);
}

private static void validateWildFlyHome(final Path wildflyHome) {
if (!ServerManager.isValidHomeDirectory(wildflyHome)) {
throw new RuntimeException("Invalid WildFly home directory: " + wildflyHome);
Expand Down
Loading

0 comments on commit d3e7e60

Please sign in to comment.