Skip to content

Commit

Permalink
[WFCORE-7120] Factor out the embedded bootstrap code that requires se…
Browse files Browse the repository at this point in the history
…rver-side types

 Move the server-side embedding logic to the server and host-controller modules
  • Loading branch information
bstansberry committed Dec 27, 2024
1 parent 604e53e commit c17b69c
Show file tree
Hide file tree
Showing 39 changed files with 1,254 additions and 692 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/

package org.jboss.as.controller.client;

import java.io.IOException;

import org.jboss.as.controller.client.logging.ControllerClientLogger;
import org.jboss.dmr.ModelNode;

/**
* A {@link ModelControllerClient} subinterface that does not throw {@link java.io.IOException}.
* Used for clients that operate in the same VM as the target {@code ModelController} and hence
* are not subject to IO failures associated with remote calls.
*
* @author Brian Stansberry
*/
public interface LocalModelControllerClient extends ModelControllerClient {

@Override
default ModelNode execute(ModelNode operation) {
return execute(Operation.Factory.create(operation), OperationMessageHandler.DISCARD);
}

@Override
default ModelNode execute(Operation operation) {
return execute(operation, OperationMessageHandler.DISCARD);
}

@Override
default ModelNode execute(ModelNode operation, OperationMessageHandler messageHandler) {
return execute(Operation.Factory.create(operation), messageHandler);
}

@Override
default ModelNode execute(Operation operation, OperationMessageHandler messageHandler) {
OperationResponse or = executeOperation(operation, messageHandler);
ModelNode result = or.getResponseNode();
try {
or.close();
} catch (IOException e) {
ControllerClientLogger.ROOT_LOGGER.debugf(e, "Failed closing response to %s", operation);
}
return result;
}

@Override
OperationResponse executeOperation(Operation operation, OperationMessageHandler messageHandler);

@Override
void close();
}
4 changes: 4 additions & 0 deletions controller/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<groupId>org.wildfly.core</groupId>
<artifactId>wildfly-core-security</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.core</groupId>
<artifactId>wildfly-embedded</artifactId>
</dependency>

<dependency>
<groupId>org.wildfly.security</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StartException;
import org.jboss.msc.service.StopContext;
import org.wildfly.core.embedded.spi.EmbeddedModelControllerClientFactory;
import org.wildfly.security.manager.WildFlySecurityManager;

/**
Expand Down Expand Up @@ -336,7 +337,8 @@ bootErrorCollector, createExtraValidationStepHandler(), capabilityRegistry, getP
rootResourceRegistration.registerCapability(NOTIFICATION_REGISTRY_CAPABILITY);
final ServiceName clientFactorySN = CLIENT_FACTORY_CAPABILITY.getCapabilityServiceName();
final ServiceBuilder<?> clientFactorySB = target.addService(clientFactorySN);
clientFactorySB.setInstance(new SimpleService(clientFactorySB.provides(clientFactorySN), clientFactory));
clientFactorySB.setInstance(new SimpleService(clientFactorySB.provides(clientFactorySN,
EmbeddedModelControllerClientFactory.SERVICE_NAME), clientFactory));
clientFactorySB.install();
final ServiceName notifyRegistrySN = NOTIFICATION_REGISTRY_CAPABILITY.getCapabilityServiceName();
final ServiceBuilder<?> notifyRegistrySB = target.addService(notifyRegistrySN);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

import org.wildfly.core.embedded.spi.EmbeddedProcessState;

/**
* The overall state of a process that is being managed by a {@link ModelController}.
*
Expand All @@ -19,11 +21,11 @@ public enum State {
/**
* The process is starting and its runtime state is being made consistent with its persistent configuration.
*/
STARTING("starting", false),
STARTING(EmbeddedProcessState.STARTING, false),
/**
* The process is started, is running normally and has a runtime state consistent with its persistent configuration.
*/
RUNNING("running", true),
RUNNING(EmbeddedProcessState.RUNNING, true),
/**
* The process requires a stop and re-start of its root service (but not a full process restart) in order to
* ensure stable operation and/or to bring its running state in line with its persistent configuration. A
Expand All @@ -32,22 +34,22 @@ public enum State {
* handle external requests is similar to that of a full process restart. However, a reload can execute more
* quickly than a full process restart.
*/
RELOAD_REQUIRED("reload-required", true),
RELOAD_REQUIRED(EmbeddedProcessState.RELOAD_REQUIRED, true),
/**
* The process must be terminated and replaced with a new process in order to ensure stable operation and/or to bring
* the running state in line with the persistent configuration.
*/
RESTART_REQUIRED("restart-required", true),
RESTART_REQUIRED(EmbeddedProcessState.RESTART_REQUIRED, true),
/** The process is stopping. */
STOPPING("stopping", false),
STOPPING(EmbeddedProcessState.STOPPING, false),
/** The process is stopped */
STOPPED("stopped", false);
STOPPED(EmbeddedProcessState.STOPPED, false);

private final String stringForm;
private final EmbeddedProcessState embeddedForm;
private final boolean running;

State(final String stringForm, final boolean running) {
this.stringForm = stringForm;
State(final EmbeddedProcessState embeddedForm, final boolean running) {
this.embeddedForm = embeddedForm;
this.running = running;
}

Expand All @@ -65,7 +67,11 @@ public boolean isRunning() {

@Override
public String toString() {
return stringForm;
return embeddedForm.toString();
}

EmbeddedProcessState getEmbeddedProcessState() {
return embeddedForm;
}

}
Expand All @@ -81,8 +87,12 @@ public String toString() {
private boolean restartRequiredOnStarting = false;

public ControlledProcessState(final boolean reloadSupported) {
this(reloadSupported, false);
}

public ControlledProcessState(final boolean reloadSupported, boolean embedded) {
this.reloadSupported = reloadSupported;
service = new ControlledProcessStateService(State.STOPPED);
service = new ControlledProcessStateService(State.STOPPED, embedded);
}

public State getState() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceTarget;
import org.wildfly.core.embedded.spi.EmbeddedProcessState;

/**
* Exposes the current {@link ControlledProcessState.State} and allows services to register a listener for changes
Expand All @@ -21,7 +22,7 @@
* @author Brian Stansberry (c) 2011 Red Hat Inc.
* @author <a href="mailto:[email protected]">Richard Opalka</a>
*/
public class ControlledProcessStateService implements ProcessStateNotifier {
public class ControlledProcessStateService implements ProcessStateNotifier, org.wildfly.core.embedded.spi.ProcessStateNotifier {

/** @deprecated use the 'org.wildfly.management.process-state-notifier' capability to obtain a {@link ProcessStateNotifier}*/
@Deprecated(forRemoval = true)
Expand All @@ -41,18 +42,20 @@ public class ControlledProcessStateService implements ProcessStateNotifier {
public static ProcessStateNotifier addService(ServiceTarget target, ControlledProcessState processState) {
final ControlledProcessStateService notifier = processState.getService();
final ServiceBuilder<?> sb = target.addService();
Consumer<ProcessStateNotifier> consumer = sb.provides(INTERNAL_SERVICE_NAME, SERVICE_NAME);
Consumer<ProcessStateNotifier> consumer = sb.provides(INTERNAL_SERVICE_NAME, SERVICE_NAME, org.wildfly.core.embedded.spi.ProcessStateNotifier.SERVICE_NAME);
sb.setInstance(Service.newInstance(consumer, notifier));
sb.install();
return notifier;
}

private ControlledProcessState.State processState;
private final PropertyChangeSupport changeSupport;
private final boolean embedded;

ControlledProcessStateService(ControlledProcessState.State initialState) {
ControlledProcessStateService(ControlledProcessState.State initialState, boolean embedded) {
this.processState = initialState;
changeSupport = new PropertyChangeSupport(this);
this.changeSupport = new PropertyChangeSupport(this);
this.embedded = embedded;
}

/**
Expand All @@ -65,6 +68,17 @@ public ControlledProcessState.State getCurrentState() {
return processState;
}

/**
* Returns the current process state.
*
* @return the current state
*/
@Override
public EmbeddedProcessState getEmbeddedProcessState() {
checkEmbedded();
return processState.getEmbeddedProcessState();
}

/**
* Registers a listener for changes to the process state.
*
Expand All @@ -73,7 +87,7 @@ public ControlledProcessState.State getCurrentState() {
@Override
public void addPropertyChangeListener(
PropertyChangeListener listener) {
changeSupport.addPropertyChangeListener(listener);
changeSupport.addPropertyChangeListener("currentState", listener);
}

/**
Expand All @@ -84,12 +98,31 @@ public void addPropertyChangeListener(
@Override
public void removePropertyChangeListener(
PropertyChangeListener listener) {
changeSupport.removePropertyChangeListener(listener);
changeSupport.removePropertyChangeListener("currentState", listener);
}

@Override
public void addProcessStateListener(PropertyChangeListener listener) {
checkEmbedded();
changeSupport.addPropertyChangeListener("embeddedState", listener);
}

@Override
public void removeProcessStateListener(PropertyChangeListener listener) {
checkEmbedded();
changeSupport.removePropertyChangeListener("embeddedState", listener);
}

synchronized void stateChanged(ControlledProcessState.State newState) {
final ControlledProcessState.State oldState = processState;
processState = newState;
changeSupport.firePropertyChange("currentState", oldState, newState);
changeSupport.firePropertyChange("embeddedState", oldState.getEmbeddedProcessState(), newState.getEmbeddedProcessState());
}

private void checkEmbedded() {
if (!embedded) {
throw new IllegalStateException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,7 @@

package org.jboss.as.controller;

import java.io.IOException;

import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.client.Operation;
import org.jboss.as.controller.client.OperationMessageHandler;
import org.jboss.as.controller.client.OperationResponse;
import org.jboss.as.controller.logging.ControllerLogger;
import org.jboss.dmr.ModelNode;

/**
* A {@link ModelControllerClient} subinterface that does not throw {@link java.io.IOException}.
Expand All @@ -21,38 +14,5 @@
*
* @author Brian Stansberry
*/
public interface LocalModelControllerClient extends ModelControllerClient {

@Override
default ModelNode execute(ModelNode operation) {
return execute(Operation.Factory.create(operation), OperationMessageHandler.DISCARD);
}

@Override
default ModelNode execute(Operation operation) {
return execute(operation, OperationMessageHandler.DISCARD);
}

@Override
default ModelNode execute(ModelNode operation, OperationMessageHandler messageHandler) {
return execute(Operation.Factory.create(operation), messageHandler);
}

@Override
default ModelNode execute(Operation operation, OperationMessageHandler messageHandler) {
OperationResponse or = executeOperation(operation, messageHandler);
ModelNode result = or.getResponseNode();
try {
or.close();
} catch (IOException e) {
ControllerLogger.MGMT_OP_LOGGER.debugf(e, "Failed closing response to %s", operation);
}
return result;
}

@Override
OperationResponse executeOperation(Operation operation, OperationMessageHandler messageHandler);

@Override
void close();
public interface LocalModelControllerClient extends org.jboss.as.controller.client.LocalModelControllerClient {
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.jboss.dmr.ModelNode;
import org.jboss.threads.AsyncFuture;
import org.jboss.threads.AsyncFutureTask;
import org.wildfly.core.embedded.spi.EmbeddedModelControllerClientFactory;
import org.wildfly.security.auth.server.SecurityIdentity;
import org.wildfly.security.manager.WildFlySecurityManager;

Expand All @@ -45,7 +46,7 @@
*
* @author Brian Stansberry
*/
final class ModelControllerClientFactoryImpl implements ModelControllerClientFactory {
final class ModelControllerClientFactoryImpl implements ModelControllerClientFactory, EmbeddedModelControllerClientFactory {

private final ModelControllerImpl modelController;
private final Supplier<SecurityIdentity> securityIdentitySupplier;
Expand All @@ -65,6 +66,11 @@ public LocalModelControllerClient createSuperUserClient(Executor executor, boole
return createSuperUserClient(executor, forUserCalls, false);
}

@Override
public org.jboss.as.controller.client.LocalModelControllerClient createEmbeddedClient(Executor executor) {
return createSuperUserClient(executor, true);
}

/**
* Creates a superuser client that can execute calls that are to be regarded as part of process boot.
* Package protected as this facility should only be made available to kernel code.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
* @author Brian Stansberry (c) 2019 Red Hat Inc.
*/
public interface ProcessStateNotifier {
NullaryServiceDescriptor<ProcessStateNotifier> SERVICE_DESCRIPTOR = NullaryServiceDescriptor.of("org.wildfly.management.process-state-notifier", ProcessStateNotifier.class);
NullaryServiceDescriptor<ProcessStateNotifier> SERVICE_DESCRIPTOR =
NullaryServiceDescriptor.of("org.wildfly.management.process-state-notifier", ProcessStateNotifier.class);

/**
* Gets the current state of the controlled process.
Expand Down
Loading

0 comments on commit c17b69c

Please sign in to comment.