diff --git a/cli/src/main/java/org/jboss/as/cli/Util.java b/cli/src/main/java/org/jboss/as/cli/Util.java index 024098a0b58..9dae435341c 100644 --- a/cli/src/main/java/org/jboss/as/cli/Util.java +++ b/cli/src/main/java/org/jboss/as/cli/Util.java @@ -230,6 +230,7 @@ public class Util { public static final String RELEASE_CODENAME = "release-codename"; public static final String RELEASE_VERSION = "release-version"; public static final String RELOAD = "reload"; + public static final String RELOAD_ENHANCED = "reload-enhanced"; public static final String REMOVE = "remove"; public static final String REPLY_PROPERTIES = "reply-properties"; public static final String REQUEST_PROPERTIES = "request-properties"; diff --git a/cli/src/main/java/org/jboss/as/cli/impl/CommandContextImpl.java b/cli/src/main/java/org/jboss/as/cli/impl/CommandContextImpl.java index 37155a1fcb1..2b7914d42d9 100644 --- a/cli/src/main/java/org/jboss/as/cli/impl/CommandContextImpl.java +++ b/cli/src/main/java/org/jboss/as/cli/impl/CommandContextImpl.java @@ -2003,7 +2003,7 @@ public void handleClose() { // if the connection loss was triggered by an instruction to restart/reload // then we don't disconnect yet if(parsedCmd.getFormat() != null) { - if(Util.RELOAD.equals(parsedCmd.getOperationName())) { + if(Util.RELOAD.equals(parsedCmd.getOperationName()) || Util.RELOAD_ENHANCED.equals(parsedCmd.getOperationName())) { // do nothing } else if(Util.SHUTDOWN.equals(parsedCmd.getOperationName())) { if(CommandFormat.INSTANCE.equals(parsedCmd.getFormat()) diff --git a/controller/src/main/java/org/jboss/as/controller/descriptions/ModelDescriptionConstants.java b/controller/src/main/java/org/jboss/as/controller/descriptions/ModelDescriptionConstants.java index e856e8bef10..f530f24b33c 100644 --- a/controller/src/main/java/org/jboss/as/controller/descriptions/ModelDescriptionConstants.java +++ b/controller/src/main/java/org/jboss/as/controller/descriptions/ModelDescriptionConstants.java @@ -419,6 +419,7 @@ public class ModelDescriptionConstants { public static final String RELEASE_CODENAME = "release-codename"; public static final String RELEASE_VERSION = "release-version"; public static final String RELOAD = "reload"; + public static final String RELOAD_ENHANCED = "reload-enhanced"; public static final String RELOAD_REQUIRED = "reload-required"; public static final String REMOVE = "remove"; public static final String REMOTE = "remote"; diff --git a/controller/src/main/java/org/jboss/as/controller/remote/ModelControllerClientOperationHandler.java b/controller/src/main/java/org/jboss/as/controller/remote/ModelControllerClientOperationHandler.java index 9a8a1f6722b..a998802da7d 100644 --- a/controller/src/main/java/org/jboss/as/controller/remote/ModelControllerClientOperationHandler.java +++ b/controller/src/main/java/org/jboss/as/controller/remote/ModelControllerClientOperationHandler.java @@ -17,6 +17,7 @@ import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OUTCOME; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RELOAD; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RELOAD_ENHANCED; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RESULT; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SHUTDOWN; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUCCESS; @@ -68,7 +69,7 @@ */ public class ModelControllerClientOperationHandler implements ManagementRequestHandlerFactory { - private static final Set PREPARED_RESPONSE_OPERATIONS = Set.of(RELOAD, SHUTDOWN); + private static final Set PREPARED_RESPONSE_OPERATIONS = Set.of(RELOAD, RELOAD_ENHANCED, SHUTDOWN); private final ModelController controller; private final ManagementChannelAssociation channelAssociation; @@ -193,7 +194,7 @@ public void operationPrepared(ModelController.OperationTransaction transaction, @Override public void operationPrepared(ModelController.OperationTransaction transaction, final ModelNode preparedResult, OperationContext context) { transaction.commit(); - if (context == null || !RELOAD.equals(operation.get(OP).asString())) { // TODO deal with shutdown as well, + if (context == null || !RELOAD.equals(operation.get(OP).asString()) || !RELOAD_ENHANCED.equals(operation.get(OP).asString())) { // TODO deal with shutdown as well, // the handlers for which have some // subtleties that need thought sendResponse(preparedResult); diff --git a/domain-http/interface/src/main/java/org/jboss/as/domain/http/server/EarlyResponseTransactionControl.java b/domain-http/interface/src/main/java/org/jboss/as/domain/http/server/EarlyResponseTransactionControl.java index 8dd89595f23..40f2f38e35d 100644 --- a/domain-http/interface/src/main/java/org/jboss/as/domain/http/server/EarlyResponseTransactionControl.java +++ b/domain-http/interface/src/main/java/org/jboss/as/domain/http/server/EarlyResponseTransactionControl.java @@ -8,6 +8,7 @@ import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OUTCOME; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RELOAD; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RELOAD_ENHANCED; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RESULT; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUCCESS; @@ -29,7 +30,7 @@ final class EarlyResponseTransactionControl implements ModelController.Operation EarlyResponseTransactionControl(ResponseCallback callback, ModelNode operation) { this.callback = callback; - this.reload = RELOAD.equals(operation.get(OP).asString()); + this.reload = RELOAD.equals(operation.get(OP).asString()) || RELOAD_ENHANCED.equals(operation.get(OP).asString()); } @Override diff --git a/server/src/main/java/org/jboss/as/server/controller/resources/ServerRootResourceDefinition.java b/server/src/main/java/org/jboss/as/server/controller/resources/ServerRootResourceDefinition.java index 21f593bae9e..8135be4c5f9 100644 --- a/server/src/main/java/org/jboss/as/server/controller/resources/ServerRootResourceDefinition.java +++ b/server/src/main/java/org/jboss/as/server/controller/resources/ServerRootResourceDefinition.java @@ -413,8 +413,9 @@ public void registerOperations(ManagementResourceRegistration resourceRegistrati resourceRegistration.registerOperationHandler(ServerDomainProcessShutdownHandler.DOMAIN_DEFINITION, new ServerDomainProcessShutdownHandler()); } else { - final ServerProcessReloadHandler reloadHandler = new ServerProcessReloadHandler(Services.JBOSS_AS, runningModeControl, processState, serverEnvironment); - resourceRegistration.registerOperationHandler(ServerProcessReloadHandler.DEFINITION, reloadHandler, false); + + ServerProcessReloadHandler.registerStandardReloadOperation(resourceRegistration, runningModeControl, processState, serverEnvironment); + ServerProcessReloadHandler.registerEnhancedReloadOperation(resourceRegistration, runningModeControl, processState, serverEnvironment); resourceRegistration.registerOperationHandler(ServerSuspendHandler.DEFINITION, ServerSuspendHandler.INSTANCE); resourceRegistration.registerOperationHandler(ServerResumeHandler.DEFINITION, ServerResumeHandler.INSTANCE); diff --git a/server/src/main/java/org/jboss/as/server/operations/ServerProcessReloadHandler.java b/server/src/main/java/org/jboss/as/server/operations/ServerProcessReloadHandler.java index 077931ed5ff..86ccfc0a4b1 100644 --- a/server/src/main/java/org/jboss/as/server/operations/ServerProcessReloadHandler.java +++ b/server/src/main/java/org/jboss/as/server/operations/ServerProcessReloadHandler.java @@ -19,7 +19,9 @@ import org.jboss.as.controller.descriptions.ModelDescriptionConstants; import org.jboss.as.controller.operations.common.ProcessReloadHandler; import org.jboss.as.controller.operations.validation.EnumValidator; +import org.jboss.as.controller.registry.ManagementResourceRegistration; import org.jboss.as.server.ServerEnvironment; +import org.jboss.as.server.Services; import org.jboss.as.server.controller.descriptions.ServerDescriptions; import org.jboss.as.server.logging.ServerLogger; import org.jboss.as.version.Stability; @@ -27,7 +29,10 @@ import org.jboss.dmr.ModelType; import org.jboss.msc.service.ServiceName; +import java.util.Collections; +import java.util.HashSet; import java.util.Locale; +import java.util.Set; /** * @@ -54,33 +59,73 @@ public class ServerProcessReloadHandler extends ProcessReloadHandler additionalAttributes; private final ServerEnvironment environment; - public ServerProcessReloadHandler(ServiceName rootService, RunningModeControl runningModeControl, - ControlledProcessState processState, ServerEnvironment environment) { + + public ServerProcessReloadHandler(ServiceName rootService, RunningModeControl runningModeControl, ControlledProcessState processState, ServerEnvironment environment) { + this(rootService, runningModeControl, processState, environment, null); + } + + public ServerProcessReloadHandler(ServiceName rootService, RunningModeControl runningModeControl, ControlledProcessState processState, ServerEnvironment environment, Set additionalAttributes) { super(rootService, runningModeControl, processState); + this.additionalAttributes = additionalAttributes == null ? Collections.emptySet() : additionalAttributes; this.environment = environment; } + public static void registerStandardReloadOperation(ManagementResourceRegistration resourceRegistration, RunningModeControl runningModeControl, ControlledProcessState processState, ServerEnvironment serverEnvironment) { + ServerProcessReloadHandler reloadHandler = new ServerProcessReloadHandler(Services.JBOSS_AS, runningModeControl, processState, serverEnvironment); + resourceRegistration.registerOperationHandler(ServerProcessReloadHandler.STANDARD_DEFINITION, reloadHandler, false); + } + + public static void registerEnhancedReloadOperation(ManagementResourceRegistration resourceRegistration, RunningModeControl runningModeControl, ControlledProcessState processState, ServerEnvironment serverEnvironment) { + ServerProcessReloadHandler reloadHandler = new ServerProcessReloadHandler(Services.JBOSS_AS, runningModeControl, processState, serverEnvironment, getAttributeNames(ENHANCED_ATTRIBUTES)); + resourceRegistration.registerOperationHandler(ServerProcessReloadHandler.ENHANCED_DEFINITION, reloadHandler, false); + } + + private static Set getAttributeNames(AttributeDefinition[] attributes) { + Set names = new HashSet<>(); + for (AttributeDefinition attr : attributes) { + names.add(attr.getName()); + } + return names; + } + @Override protected ProcessReloadHandler.ReloadContext initializeReloadContext(final OperationContext context, final ModelNode operation) throws OperationFailedException { + + System.out.println("======> RELOADING " + context.getCurrentOperationName()); + + final boolean unmanaged = context.getProcessType() != ProcessType.DOMAIN_SERVER; // make sure that the params are ignored for managed servers boolean adminOnly = unmanaged && ADMIN_ONLY.resolveModelAttribute(context, operation).asBoolean(false); final boolean useCurrentConfig = unmanaged && USE_CURRENT_SERVER_CONFIG.resolveModelAttribute(context, operation).asBoolean(true); final String startMode = START_MODE.resolveModelAttribute(context, operation).asString(); final Stability stability; - if (operation.hasDefined(ModelDescriptionConstants.STABILITY)) { + if (additionalAttributes.contains(ModelDescriptionConstants.STABILITY) && operation.hasDefined(ModelDescriptionConstants.STABILITY)) { String val = STABILITY.resolveModelAttribute(context, operation).asString(); stability = Stability.fromString(val); } else { @@ -91,8 +136,6 @@ protected ProcessReloadHandler.ReloadContext initializeReloa throw ServerLogger.ROOT_LOGGER.cannotSpecifyBothAdminOnlyAndStartMode(); } - - boolean suspend = false; if(!adminOnly) { switch (startMode.toLowerCase(Locale.ENGLISH)) { diff --git a/server/src/main/resources/org/jboss/as/server/controller/descriptions/LocalDescriptions.properties b/server/src/main/resources/org/jboss/as/server/controller/descriptions/LocalDescriptions.properties index 1917c69ecc4..9a5c7decddd 100644 --- a/server/src/main/resources/org/jboss/as/server/controller/descriptions/LocalDescriptions.properties +++ b/server/src/main/resources/org/jboss/as/server/controller/descriptions/LocalDescriptions.properties @@ -66,12 +66,21 @@ server.reload=Reloads the server by shutting down all its services and starting server.reload.admin-only=Whether the server should start in running mode ADMIN_ONLY when it restarts. An ADMIN_ONLY server will start any configured management interfaces and accept management requests, but will not start services used for handling end user requests. server.reload.use-current-server-config=Only has an effect if --read-only-server-config was specified when starting the server. In that case, if this parameter is set to false the reloaded server loads the original configuration version; if null or true the current runtime version of the model is used. server.reload.server-config=Use to override the name of the server config to use for the reloaded server. When making changes to the model after the reload, the changes will still be persisted to the original server configuration file that was first used to boot up the server. This parameter is resolved the same way as the --server-config command-line option. -server.reload.stability=Set to change the stabilty level of the reloaded server. server.reload.start-mode=Can be either normal, suspend or admin-only. If it is suspend the server will be started in suspended mode, if it is admin only the server will be started in admin-only mode. server.reload.admin-only.deprecated=Use start-mode=admin-only instead. server.reload.blocking=Whether the operation should block and wait until the server is reloaded. server.reload.reply=The status of the server following execution of this operation. server.reload.deprecated=This operation may be removed from the server-config resource in a future version; use the /host=*/server= resource for server lifecycle operations. +server.reload-enhanced=Reloads the server by shutting down all its services and starting again. The JVM itself is not restarted. This is similar to the 'reload' operation, but exposes some more advanced options. +server.reload-enhanced.admin-only=Whether the server should start in running mode ADMIN_ONLY when it restarts. An ADMIN_ONLY server will start any configured management interfaces and accept management requests, but will not start services used for handling end user requests. +server.reload-enhanced.use-current-server-config=Only has an effect if --read-only-server-config was specified when starting the server. In that case, if this parameter is set to false the reloaded server loads the original configuration version; if null or true the current runtime version of the model is used. +server.reload-enhanced.server-config=Use to override the name of the server config to use for the reloaded server. When making changes to the model after the reload, the changes will still be persisted to the original server configuration file that was first used to boot up the server. This parameter is resolved the same way as the --server-config command-line option. +server.reload-enhanced.stability=Set to change the stabilty level of the reloaded server. +server.reload-enhanced.start-mode=Can be either normal, suspend or admin-only. If it is suspend the server will be started in suspended mode, if it is admin only the server will be started in admin-only mode. +server.reload-enhanced.admin-only.deprecated=Use start-mode=admin-only instead. +server.reload-enhanced.blocking=Whether the operation should block and wait until the server is reloaded. +server.reload-enhanced.reply=The status of the server following execution of this operation. +server.reload-enhanced.deprecated=This operation may be removed from the server-config resource in a future version; use the /host=*/server= resource for server lifecycle operations. server.start=Start a server. server.start.blocking=Whether the operation should block and wait until the server is started. server.start.start-mode=The mode the servers should started in, can be either suspend or normal. diff --git a/testsuite/shared/src/main/java/org/jboss/as/test/integration/management/util/ServerReload.java b/testsuite/shared/src/main/java/org/jboss/as/test/integration/management/util/ServerReload.java index 47c156b240f..df3e0030e17 100644 --- a/testsuite/shared/src/main/java/org/jboss/as/test/integration/management/util/ServerReload.java +++ b/testsuite/shared/src/main/java/org/jboss/as/test/integration/management/util/ServerReload.java @@ -89,10 +89,12 @@ public static void executeReloadAndWaitForCompletion(ModelControllerClient clien private static void executeReload(ModelControllerClient client, Parameters parameters) { ModelNode operation = new ModelNode(); operation.get(OP_ADDR).setEmptyList(); - operation.get(OP).set("reload"); operation.get("admin-only").set(parameters.adminOnly); if (parameters.stability != null) { + operation.get(OP).set("reload-enhanced"); operation.get("stability").set(parameters.stability.toString()); + } else { + operation.get(OP).set("reload"); } executeReload(client, operation); diff --git a/testsuite/shared/src/main/java/org/wildfly/test/stability/StabilityServerSetupTasks.java b/testsuite/shared/src/main/java/org/wildfly/test/stability/StabilityServerSetupTasks.java index 5cdc80d53d8..f166fbafbf7 100644 --- a/testsuite/shared/src/main/java/org/wildfly/test/stability/StabilityServerSetupTasks.java +++ b/testsuite/shared/src/main/java/org/wildfly/test/stability/StabilityServerSetupTasks.java @@ -48,14 +48,14 @@ public abstract class StabilityServerSetupTasks implements ServerSetupTask { public StabilityServerSetupTasks(Stability desiredStability) { this.desiredStability = desiredStability; - // We can't reload to default since that will not have the stability paremeter in the reload operation - Assume.assumeFalse(desiredStability.equals(Stability.DEFAULT)); } @Override public void setup(ManagementClient managementClient) throws Exception { - reloadToDesiredStability(managementClient.getControllerClient(), desiredStability); + // We can't reload to default since that will not have the stability paremeter in the reload operation + Assume.assumeFalse(desiredStability.equals(Stability.DEFAULT)); + reloadToDesiredStability(managementClient.getControllerClient(), desiredStability); } @Override diff --git a/testsuite/standalone/src/test/java/org/wildfly/core/test/standalone/stability/StabilityDefaultServerSetupTestCase.java b/testsuite/standalone/src/test/java/org/wildfly/core/test/standalone/stability/StabilityDefaultServerSetupTestCase.java index a8d06097153..7f817551f29 100644 --- a/testsuite/standalone/src/test/java/org/wildfly/core/test/standalone/stability/StabilityDefaultServerSetupTestCase.java +++ b/testsuite/standalone/src/test/java/org/wildfly/core/test/standalone/stability/StabilityDefaultServerSetupTestCase.java @@ -31,4 +31,5 @@ public class StabilityDefaultServerSetupTestCase extends AbstractStabilityServer public StabilityDefaultServerSetupTestCase() { super(Stability.DEFAULT); } + } diff --git a/testsuite/test-runner/src/main/java/org/wildfly/core/testrunner/WildFlyRunner.java b/testsuite/test-runner/src/main/java/org/wildfly/core/testrunner/WildFlyRunner.java index 986b134c633..f910d05c975 100644 --- a/testsuite/test-runner/src/main/java/org/wildfly/core/testrunner/WildFlyRunner.java +++ b/testsuite/test-runner/src/main/java/org/wildfly/core/testrunner/WildFlyRunner.java @@ -5,6 +5,19 @@ package org.wildfly.core.testrunner; +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.security.Provider; +import java.security.Security; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + import org.jboss.as.controller.client.ModelControllerClient; import org.jboss.dmr.ModelNode; import org.junit.AssumptionViolatedException; @@ -19,21 +32,6 @@ import org.junit.runners.model.TestClass; import org.wildfly.security.WildFlyElytronProvider; -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.security.Provider; -import java.security.Security; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - /** * A lightweight test runner for running management based tests * @@ -67,6 +65,11 @@ public class WildFlyRunner extends BlockJUnit4ClassRunner { private final ParameterDescriptions parameterDescriptions = new ParameterDescriptions(); + private org.junit.internal.AssumptionViolatedException assumptionFailedInServerSetup; + private int runSetupTasks = 0; + + + /** * Creates a BlockJUnit4ClassRunner to run {@code klass} * @@ -157,6 +160,8 @@ protected Statement methodInvoker(final FrameworkMethod method, final Object tes @Override public void run(final RunNotifier notifier) { + assumptionFailedInServerSetup = null; + int setupTasks = 0; notifier.addListener(new RunListener() { @Override public void testRunFinished(Result result) throws Exception { @@ -176,10 +181,17 @@ public void testRunFinished(Result result) throws Exception { Security.insertProviderAt(ELYTRON_PROVIDER, 0); providerInstalled = true; } - if (automaticServerControl) { - runSetupTasks(); + boolean setupWorked = false; + try { + if (automaticServerControl) { + runSetupTasks(); + } + setupWorked = true; + } catch (AssumptionViolatedException e) { + assumptionFailedInServerSetup = e; } super.run(notifier); + if (automaticServerControl) { runTearDownTasks(); } @@ -192,6 +204,9 @@ private void runSetupTasks() { for (ServerSetupTask task : serverSetupTasks) { try { task.setup(controller.getClient()); + runSetupTasks++; + } catch (AssumptionViolatedException e) { + throw e; } catch (Exception e) { throw new RuntimeException(String.format("Could not run setup task '%s'", task), e); } @@ -199,7 +214,7 @@ private void runSetupTasks() { } private void runTearDownTasks() { - List reverseServerSetupTasks = new LinkedList<>(serverSetupTasks); + List reverseServerSetupTasks = new LinkedList<>(serverSetupTasks.subList(0, runSetupTasks)); Collections.reverse(reverseServerSetupTasks); for (ServerSetupTask task : reverseServerSetupTasks) { try { @@ -211,7 +226,7 @@ private void runTearDownTasks() { checkServerState(); } - private void prepareSetupTasks(TestClass klass) throws AssumptionViolatedException, RuntimeException { + private void prepareSetupTasks(TestClass klass) { try { if (klass.getJavaClass().isAnnotationPresent(ServerSetup.class)) { ServerSetup serverSetup = klass.getAnnotation(ServerSetup.class); @@ -222,16 +237,6 @@ private void prepareSetupTasks(TestClass klass) throws AssumptionViolatedExcepti } } } catch (Exception e) { - Set seen = new HashSet<>(); - Throwable cause = e.getCause(); - while (cause != null && !seen.contains(cause)) { - if (cause instanceof AssumptionViolatedException) { - throw (AssumptionViolatedException) cause; - } - seen.add(cause); - cause = cause.getCause(); - } - throw new RuntimeException(e); } } @@ -313,4 +318,25 @@ private static List> getInjectClasses() { return INJECT_CLASSES; } + @Override + protected Statement classBlock(RunNotifier notifier) { + Statement statement = super.classBlock(notifier); + return new WrappedStatement(statement); + } + + private class WrappedStatement extends Statement { + + private final Statement delegate; + public WrappedStatement(Statement delegate) { + this.delegate = delegate; + } + + @Override + public void evaluate() throws Throwable { + if (assumptionFailedInServerSetup != null) { + throw assumptionFailedInServerSetup; + } + delegate.evaluate(); + } + } }