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/RunningModeControl.java b/controller/src/main/java/org/jboss/as/controller/RunningModeControl.java index ffba4eab7b5..b86220ea882 100644 --- a/controller/src/main/java/org/jboss/as/controller/RunningModeControl.java +++ b/controller/src/main/java/org/jboss/as/controller/RunningModeControl.java @@ -5,6 +5,8 @@ package org.jboss.as.controller; +import org.jboss.as.version.Stability; + /** * Provides control over the server's current {@link RunningMode}. * @@ -18,6 +20,11 @@ public class RunningModeControl { private volatile String newBootFileName; private volatile Boolean suspend; + + // Temporary experiment for the testsuite + @Deprecated + private volatile Stability reloadedStability; + public RunningModeControl(final RunningMode initialMode) { this.runningMode = initialMode; } @@ -81,4 +88,22 @@ public String getAndClearNewBootFileName() { public void setNewBootFileName(String newBootFileName) { this.newBootFileName = newBootFileName; } + + /** + * Gets the stability of the reloaded server. + * + * @return the stability of the reloaded server + */ + public Stability getReloadedStability() { + return reloadedStability; + } + + /** + * Sets the stability of the reloaded server. + * + * @param reloadedStability the stability of the reloaded server + */ + public void setReloadedStability(Stability reloadedStability) { + this.reloadedStability = reloadedStability; + } } diff --git a/controller/src/main/java/org/jboss/as/controller/access/constraint/SensitivityClassification.java b/controller/src/main/java/org/jboss/as/controller/access/constraint/SensitivityClassification.java index 3906a9e1a01..1cb2d8b1725 100644 --- a/controller/src/main/java/org/jboss/as/controller/access/constraint/SensitivityClassification.java +++ b/controller/src/main/java/org/jboss/as/controller/access/constraint/SensitivityClassification.java @@ -27,6 +27,7 @@ public class SensitivityClassification extends AbstractSensitivity { public static final SensitivityClassification MODULE_LOADING = new SensitivityClassification("module-loading", false, false, true); public static final SensitivityClassification PATCHING = new SensitivityClassification("patching", false, false, true); public static final SensitivityClassification READ_WHOLE_CONFIG = new SensitivityClassification("read-whole-config", false, true, true); + public static final SensitivityClassification RELOAD_ENHANCED = new SensitivityClassification("reload-enhanced", false, false, false); public static final SensitivityClassification SECURITY_REALM = new SensitivityClassification("security-realm", true, true, true); public static final SensitivityClassification SECURITY_REALM_REF = new SensitivityClassification("security-realm-ref", true, true, true); public static final SensitivityClassification SECURITY_DOMAIN = new SensitivityClassification("security-domain", true, true, true); diff --git a/controller/src/main/java/org/jboss/as/controller/access/management/SensitiveTargetAccessConstraintDefinition.java b/controller/src/main/java/org/jboss/as/controller/access/management/SensitiveTargetAccessConstraintDefinition.java index c33de11eca6..e7da1cc81ad 100644 --- a/controller/src/main/java/org/jboss/as/controller/access/management/SensitiveTargetAccessConstraintDefinition.java +++ b/controller/src/main/java/org/jboss/as/controller/access/management/SensitiveTargetAccessConstraintDefinition.java @@ -35,6 +35,7 @@ public class SensitiveTargetAccessConstraintDefinition implements AccessConstrai public static final SensitiveTargetAccessConstraintDefinition MODULE_LOADING = new SensitiveTargetAccessConstraintDefinition(SensitivityClassification.MODULE_LOADING); public static final SensitiveTargetAccessConstraintDefinition PATCHING = new SensitiveTargetAccessConstraintDefinition(SensitivityClassification.PATCHING); public static final SensitiveTargetAccessConstraintDefinition READ_WHOLE_CONFIG = new SensitiveTargetAccessConstraintDefinition(SensitivityClassification.READ_WHOLE_CONFIG); + public static final SensitiveTargetAccessConstraintDefinition RELOAD_ENHANCED = new SensitiveTargetAccessConstraintDefinition(SensitivityClassification.RELOAD_ENHANCED); public static final SensitiveTargetAccessConstraintDefinition SECURITY_DOMAIN = new SensitiveTargetAccessConstraintDefinition(SensitivityClassification.SECURITY_DOMAIN); public static final SensitiveTargetAccessConstraintDefinition SECURITY_DOMAIN_REF = new SensitiveTargetAccessConstraintDefinition(SensitivityClassification.SECURITY_DOMAIN_REF); public static final SensitiveTargetAccessConstraintDefinition SECURITY_REALM = new SensitiveTargetAccessConstraintDefinition(SensitivityClassification.SECURITY_REALM); 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..77791e4c28e 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 @@ -4,6 +4,8 @@ */ package org.jboss.as.controller.descriptions; +import java.util.Set; + /** * String constants frequently used in model descriptions. * @@ -419,6 +421,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"; @@ -614,6 +617,8 @@ public class ModelDescriptionConstants { public static final String PRIMARY = "primary"; public static final String PERFORM_INSTALLATION = "perform-installation"; + public static final Set RELOAD_OPERATIONS = Set.of(RELOAD, RELOAD_ENHANCED); + private ModelDescriptionConstants() { } } diff --git a/controller/src/main/java/org/jboss/as/controller/operations/common/ProcessReloadHandler.java b/controller/src/main/java/org/jboss/as/controller/operations/common/ProcessReloadHandler.java index 49e81b5e5ff..bc58522406a 100644 --- a/controller/src/main/java/org/jboss/as/controller/operations/common/ProcessReloadHandler.java +++ b/controller/src/main/java/org/jboss/as/controller/operations/common/ProcessReloadHandler.java @@ -34,7 +34,7 @@ public abstract class ProcessReloadHandler impleme /** * The operation name. */ - protected static final String OPERATION_NAME = "reload"; + protected static final String OPERATION_NAME = ModelDescriptionConstants.RELOAD; protected static final AttributeDefinition ADMIN_ONLY = new SimpleAttributeDefinitionBuilder(ModelDescriptionConstants.ADMIN_ONLY, ModelType.BOOLEAN, true) .setDefaultValue(ModelNode.FALSE).build(); 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..cc9236adbc4 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 @@ -16,7 +16,7 @@ import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OPERATION_HEADERS; 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_OPERATIONS; 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; @@ -32,6 +32,7 @@ import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.Collections; +import java.util.HashSet; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; @@ -68,7 +69,12 @@ */ public class ModelControllerClientOperationHandler implements ManagementRequestHandlerFactory { - private static final Set PREPARED_RESPONSE_OPERATIONS = Set.of(RELOAD, SHUTDOWN); + private static final Set PREPARED_RESPONSE_OPERATIONS; + static { + Set ops = new HashSet<>(RELOAD_OPERATIONS); + ops.add(SHUTDOWN); + PREPARED_RESPONSE_OPERATIONS = Collections.unmodifiableSet(ops); + } private final ModelController controller; private final ManagementChannelAssociation channelAssociation; @@ -193,7 +199,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_OPERATIONS.contains(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/controller/src/main/java/org/jboss/as/controller/remote/TransactionalProtocolOperationHandler.java b/controller/src/main/java/org/jboss/as/controller/remote/TransactionalProtocolOperationHandler.java index 066875dcb04..e8eec5882a2 100644 --- a/controller/src/main/java/org/jboss/as/controller/remote/TransactionalProtocolOperationHandler.java +++ b/controller/src/main/java/org/jboss/as/controller/remote/TransactionalProtocolOperationHandler.java @@ -15,7 +15,6 @@ import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP; 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.SUCCESS; import static org.jboss.as.controller.logging.ControllerLogger.MGMT_OP_LOGGER; import static org.jboss.as.controller.logging.ControllerLogger.ROOT_LOGGER; @@ -42,6 +41,7 @@ import org.jboss.as.controller.client.OperationMessageHandler; import org.jboss.as.controller.client.OperationResponse; import org.jboss.as.controller.client.impl.ModelControllerProtocol; +import org.jboss.as.controller.descriptions.ModelDescriptionConstants; import org.jboss.as.controller.logging.ControllerLogger; import org.jboss.as.controller.remote.IdentityAddressProtocolUtil.PropagatedIdentity; import org.jboss.as.protocol.StreamUtils; @@ -69,7 +69,7 @@ * @author Darran Lofthouse */ public class TransactionalProtocolOperationHandler implements ManagementRequestHandlerFactory { - private static final Set PREPARED_RESPONSE_OPERATIONS = Set.of(RELOAD); + private static final Set PREPARED_RESPONSE_OPERATIONS = ModelDescriptionConstants.RELOAD_OPERATIONS; private final ModelController controller; private final ManagementChannelAssociation channelAssociation; diff --git a/domain-http/interface/src/main/java/org/jboss/as/domain/http/server/DomainApiGenericOperationHandler.java b/domain-http/interface/src/main/java/org/jboss/as/domain/http/server/DomainApiGenericOperationHandler.java index 1fe2aead7e1..e1c53ab7441 100644 --- a/domain-http/interface/src/main/java/org/jboss/as/domain/http/server/DomainApiGenericOperationHandler.java +++ b/domain-http/interface/src/main/java/org/jboss/as/domain/http/server/DomainApiGenericOperationHandler.java @@ -26,6 +26,7 @@ import java.nio.file.Files; import java.util.Deque; import java.util.Iterator; +import java.util.Set; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; @@ -40,6 +41,7 @@ import org.jboss.as.controller.client.OperationBuilder; import org.jboss.as.controller.client.OperationMessageHandler; import org.jboss.as.controller.client.OperationResponse; +import org.jboss.as.controller.descriptions.ModelDescriptionConstants; import org.jboss.as.core.security.AccessMechanism; import org.jboss.dmr.ModelNode; import org.xnio.IoUtils; @@ -61,9 +63,12 @@ class DomainApiGenericOperationHandler implements HttpHandler { private static final String CLIENT_NAME = "X-Management-Client-Name"; + private static final Set PREPARED_RESPONSE_OPERATIONS = ModelDescriptionConstants.RELOAD_OPERATIONS; + private final ModelController modelController; private final FormParserFactory formParserFactory; + public DomainApiGenericOperationHandler(ModelController modelController) { this.modelController = modelController; this.formParserFactory = FormParserFactory.builder().build(); @@ -203,8 +208,6 @@ private static String stripSuffix(String contentType) { return contentType; } - static final String RELOAD = "reload"; - /** * Determine whether the prepared response should be sent, before the operation completed. This is needed in order * that operations like :reload() can be executed without causing communication failures. @@ -217,7 +220,7 @@ private boolean sendPreparedResponse(final ModelNode operation) { final String op = operation.get(OP).asString(); final int size = address.size(); if (size == 0) { - if (op.equals(RELOAD)) { + if (PREPARED_RESPONSE_OPERATIONS.contains(op)) { return true; } else if (op.equals(COMPOSITE)) { // TODO @@ -227,7 +230,7 @@ private boolean sendPreparedResponse(final ModelNode operation) { } } else if (size == 1) { if (address.getLastElement().getKey().equals(HOST)) { - return op.equals(RELOAD); + return PREPARED_RESPONSE_OPERATIONS.contains(op); } } return false; diff --git a/domain-http/interface/src/main/java/org/jboss/as/domain/http/server/DomainApiHandler.java b/domain-http/interface/src/main/java/org/jboss/as/domain/http/server/DomainApiHandler.java index 3fffd314edf..01d710534fd 100644 --- a/domain-http/interface/src/main/java/org/jboss/as/domain/http/server/DomainApiHandler.java +++ b/domain-http/interface/src/main/java/org/jboss/as/domain/http/server/DomainApiHandler.java @@ -39,6 +39,7 @@ import java.util.Locale; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; @@ -66,7 +67,7 @@ * @author Kabir Khan */ class DomainApiHandler implements HttpHandler { - + private static final Set PREPARED_RESPONSE_OPERATIONS = ModelDescriptionConstants.RELOAD_OPERATIONS; private static final String JSON_PRETTY = "json.pretty"; /** @@ -309,6 +310,7 @@ private String unescape(String string) { } } + /** * Determine whether the prepared response should be sent, before the operation completed. This is needed in order * that operations like :reload() can be executed without causing communication failures. @@ -321,7 +323,7 @@ private boolean sendPreparedResponse(final ModelNode operation) { final String op = operation.get(OP).asString(); final int size = address.size(); if (size == 0) { - if (op.equals("reload")) { + if (PREPARED_RESPONSE_OPERATIONS.contains(op)) { return true; } else if (op.equals(COMPOSITE)) { // TODO @@ -331,7 +333,7 @@ private boolean sendPreparedResponse(final ModelNode operation) { } } else if (size == 1) { if (address.getLastElement().getKey().equals(HOST)) { - return op.equals("reload"); + return PREPARED_RESPONSE_OPERATIONS.contains(op); } } return false; 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..e0c3418310c 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 @@ -7,13 +7,13 @@ 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.RESULT; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUCCESS; import org.jboss.as.controller.ModelController; import org.jboss.as.controller.OperationContext; import org.jboss.as.controller.client.OperationResponse; +import org.jboss.as.controller.descriptions.ModelDescriptionConstants; import org.jboss.as.controller.remote.EarlyResponseSendListener; import org.jboss.dmr.ModelNode; @@ -29,7 +29,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 = ModelDescriptionConstants.RELOAD_OPERATIONS.contains(operation.get(OP).asString()); } @Override diff --git a/server/src/main/java/org/jboss/as/server/ApplicationServerService.java b/server/src/main/java/org/jboss/as/server/ApplicationServerService.java index a67f628e8a9..5c577085a43 100644 --- a/server/src/main/java/org/jboss/as/server/ApplicationServerService.java +++ b/server/src/main/java/org/jboss/as/server/ApplicationServerService.java @@ -52,7 +52,7 @@ final class ApplicationServerService implements Service> { private final List extraServices; - private final Bootstrap.Configuration configuration; + private volatile Bootstrap.Configuration configuration; private final RunningModeControl runningModeControl; private final ControlledProcessState processState; private final SuspendController suspendController; @@ -78,8 +78,15 @@ public synchronized void start(final StartContext context) throws StartException //Moved to AbstractControllerService.start() //processState.setStarting(); - final Bootstrap.Configuration configuration = this.configuration; - final ServerEnvironment serverEnvironment = configuration.getServerEnvironment(); + final Bootstrap.Configuration configuration; + Bootstrap.Configuration recalculatedConfiguration = this.configuration.recalculateForReload(runningModeControl); + if (recalculatedConfiguration != this.configuration) { + this.configuration = recalculatedConfiguration; + configuration = recalculatedConfiguration; + } else { + configuration = this.configuration; + } + final ServerEnvironment serverEnvironment = configuration.getServerEnvironment().recalculateForReload(runningModeControl); final ProductConfig config = serverEnvironment.getProductConfig(); final String prettyVersion = config.getPrettyVersionString(); ServerLogger.AS_ROOT_LOGGER.serverStarting(prettyVersion); diff --git a/server/src/main/java/org/jboss/as/server/Bootstrap.java b/server/src/main/java/org/jboss/as/server/Bootstrap.java index 826d298650d..a4288da2dd5 100644 --- a/server/src/main/java/org/jboss/as/server/Bootstrap.java +++ b/server/src/main/java/org/jboss/as/server/Bootstrap.java @@ -100,6 +100,19 @@ public Configuration(final ServerEnvironment serverEnvironment) { this.startTime = serverEnvironment.getStartTime(); } + private Configuration(final Configuration original, ServerEnvironment serverEnvironment) { + this.serverEnvironment = serverEnvironment; + this.runningModeControl = original.runningModeControl; + this.extensionRegistry = original.extensionRegistry; + this.capabilityRegistry = original.capabilityRegistry; + this.auditLogger = original.auditLogger; + this.authorizer = original.authorizer; + this.securityIdentitySupplier = original.securityIdentitySupplier; + this.moduleLoader = original.moduleLoader; + this.configurationPersisterFactory = original.configurationPersisterFactory; + this.startTime = original.startTime; + } + /** * Get the server environment. * @@ -235,6 +248,16 @@ public synchronized void setConfigurationPersisterFactory(final ConfigurationPer public long getStartTime() { return startTime; } + + Configuration recalculateForReload(RunningModeControl runningModeControl) { + if (runningModeControl.isReloaded()) { + ServerEnvironment recalculatedServerEnvironment = serverEnvironment.recalculateForReload(runningModeControl); + if (recalculatedServerEnvironment != serverEnvironment) { + return new Configuration(this, recalculatedServerEnvironment); + } + } + return this; + } } /** A factory for the {@link ExtensibleConfigurationPersister} to be used by this server */ diff --git a/server/src/main/java/org/jboss/as/server/ServerEnvironment.java b/server/src/main/java/org/jboss/as/server/ServerEnvironment.java index 40019885b5e..3a075668802 100644 --- a/server/src/main/java/org/jboss/as/server/ServerEnvironment.java +++ b/server/src/main/java/org/jboss/as/server/ServerEnvironment.java @@ -589,6 +589,41 @@ public ServerEnvironment(final String hostControllerName, final Properties props } } + private ServerEnvironment(ServerEnvironment original, Stability stability) { + this.primordialProperties = original.primordialProperties; + this.providedProperties = original.providedProperties; + this.processNameSet = original.processNameSet; + this.launchType = original.launchType; + this.hostControllerName = original.hostControllerName; + this.qualifiedHostName = original.qualifiedHostName; + this.hostName = original.hostName; + this.serverName = original.serverName; + this.nodeName = original.nodeName; + this.javaExtDirs = original.javaExtDirs; + this.homeDir = original.homeDir; + this.serverBaseDir = original.serverBaseDir; + this.serverConfigurationDir = original.serverConfigurationDir; + this.serverConfigurationFile = original.serverConfigurationFile; + this.serverLogDir = original.serverLogDir; + this.controllerTempDir = original.controllerTempDir; + this.serverDataDir = original.serverDataDir; + this.serverContentDir = original.serverContentDir; + this.serverTempDir = original.serverTempDir; + this.domainBaseDir = original.domainBaseDir; + this.domainConfigurationDir = original.domainConfigurationDir; + this.standalone = original.standalone; + this.allowModelControllerExecutor = original.allowModelControllerExecutor; + this.initialRunningMode = original.initialRunningMode; + this.productConfig = original.productConfig; + this.runningModeControl = original.runningModeControl; + this.serverUUID = original.serverUUID; + this.startTime = original.startTime; + this.startSuspended = original.startSuspended; + this.startGracefully = original.startGracefully; + this.repository = original.repository; + this.stability = stability; + } + private Set listIgnoredFiles(String defaultServerConfig) { Set ignored = new LinkedHashSet<>(); setIgnored(ignored, serverDataDir.toPath(), true, false); @@ -1242,4 +1277,16 @@ private File[] getFilesFromProperty(final String name, final Properties props) { ManagedAuditLogger createAuditLogger() { return new ManagedAuditLoggerImpl(getProductConfig().resolveVersion(), true); } + + ServerEnvironment recalculateForReload(RunningModeControl runningModeControl) { + if (runningModeControl.isReloaded()) { + Stability stability = runningModeControl.getReloadedStability() != null ? runningModeControl.getReloadedStability() : productConfig.getDefaultStability(); + if (stability != this.stability) { + System.setProperty(ProcessEnvironment.STABILITY, stability.toString()); + + return new ServerEnvironment(this, stability); + } + } + return this; + } } diff --git a/server/src/main/java/org/jboss/as/server/ServerService.java b/server/src/main/java/org/jboss/as/server/ServerService.java index 289894124f6..1b81847d740 100644 --- a/server/src/main/java/org/jboss/as/server/ServerService.java +++ b/server/src/main/java/org/jboss/as/server/ServerService.java @@ -201,7 +201,7 @@ static ProcessType getProcessType(ServerEnvironment serverEnvironment) { : ProcessType.EMBEDDED_SERVER; } - static Stability getStability(ServerEnvironment serverEnvironment) { + private static Stability getStability(ServerEnvironment serverEnvironment) { return serverEnvironment != null ? serverEnvironment.getStability() : Stability.DEFAULT; } 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 8c9b36ac1ff..7d681634225 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 @@ -4,7 +4,10 @@ */ package org.jboss.as.server.operations; +import java.util.Collections; +import java.util.HashSet; import java.util.Locale; +import java.util.Set; import org.jboss.as.controller.AttributeDefinition; import org.jboss.as.controller.ControlledProcessState; @@ -17,12 +20,16 @@ import org.jboss.as.controller.RunningModeControl; import org.jboss.as.controller.SimpleAttributeDefinitionBuilder; import org.jboss.as.controller.SimpleOperationDefinitionBuilder; +import org.jboss.as.controller.access.management.SensitiveTargetAccessConstraintDefinition; 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; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; import org.jboss.msc.service.ServiceName; @@ -51,20 +58,61 @@ public class ServerProcessReloadHandler extends ProcessReloadHandler additionalAttributes; private final ServerEnvironment environment; - public ServerProcessReloadHandler(ServiceName rootService, RunningModeControl runningModeControl, - ControlledProcessState processState, ServerEnvironment environment) { + + protected ServerProcessReloadHandler(ServiceName rootService, RunningModeControl runningModeControl, ControlledProcessState processState, ServerEnvironment environment) { + this(rootService, runningModeControl, processState, environment, null); + } + + private 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 { final boolean unmanaged = context.getProcessType() != ProcessType.DOMAIN_SERVER; // make sure that the params are ignored for managed servers @@ -72,6 +120,14 @@ protected ProcessReloadHandler.ReloadContext initializeReloa 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 (additionalAttributes.contains(ModelDescriptionConstants.STABILITY) && operation.hasDefined(ModelDescriptionConstants.STABILITY)) { + String val = STABILITY.resolveModelAttribute(context, operation).asString(); + stability = Stability.fromString(val); + } else { + stability = null; + } + if(operation.get(ModelDescriptionConstants.ADMIN_ONLY).isDefined() && operation.get(ModelDescriptionConstants.START_MODE).isDefined()) { throw ServerLogger.ROOT_LOGGER.cannotSpecifyBothAdminOnlyAndStartMode(); } @@ -108,8 +164,12 @@ public void reloadInitiated(RunningModeControl runningModeControl) { @Override public void doReload(RunningModeControl runningModeControl) { + // If no stability is specified, use the current stability + Stability reloadedStability = stability == null ? environment.getStability() : stability; + runningModeControl.setRunningMode(finalAdminOnly ? RunningMode.ADMIN_ONLY : RunningMode.NORMAL); runningModeControl.setReloaded(); + runningModeControl.setReloadedStability(reloadedStability); runningModeControl.setUseCurrentConfig(useCurrentConfig); runningModeControl.setNewBootFileName(serverConfig); runningModeControl.setSuspend(finalSuspend); 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 3efac468bb6..86e6129853a 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 @@ -71,6 +71,16 @@ 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 stability 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.