Skip to content

Commit

Permalink
Auto-propagate extension stability to subsystem model, if necessary.
Browse files Browse the repository at this point in the history
  • Loading branch information
pferraro committed Feb 1, 2024
1 parent 1592ee4 commit 15ea126
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public void handleRollback(OperationContext context, ModelNode operation) {
});
}

void initializeExtension(String module, ManagementResourceRegistration rootRegistration) {
void initializeExtension(String module, ManagementResourceRegistration rootRegistration, PathAddress address) {
initializeExtension(extensionRegistry, module, rootRegistration, extensionRegistryType);
}

Expand All @@ -110,7 +110,7 @@ static void initializeExtension(ExtensionRegistry extensionRegistry, String modu
}
while (extensions.hasNext()) {
Extension extension = extensions.next();
if (rootRegistration.enables(extension)) {
if (extensionRegistry.enables(extension)) {
ClassLoader oldTccl = WildFlySecurityManager.setCurrentContextClassLoaderPrivileged(extension.getClass());
try {
if (unknownModule || !extensionRegistry.getExtensionModuleNames().contains(module)) {
Expand All @@ -121,7 +121,7 @@ static void initializeExtension(ExtensionRegistry extensionRegistry, String modu
// now that we know the registry was unaware of the module
unknownModule = true;
}
extension.initialize(extensionRegistry.getExtensionContext(module, rootRegistration, extensionRegistryType));
extension.initialize(extensionRegistry.getExtensionContext(module, extension.getStability(), rootRegistration, extensionRegistryType));
} finally {
WildFlySecurityManager.setCurrentContextClassLoaderPrivileged(oldTccl);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.PersistentResourceXMLParser;
import org.jboss.as.controller.ProcessType;
import org.jboss.as.controller.ProvidedResourceDefinition;
import org.jboss.as.controller.ProxyController;
import org.jboss.as.controller.ResourceDefinition;
import org.jboss.as.controller.ResourceRegistration;
import org.jboss.as.controller.RunningMode;
import org.jboss.as.controller.RunningModeControl;
import org.jboss.as.controller.SimpleResourceDefinition;
import org.jboss.as.controller.SubsystemRegistration;
import org.jboss.as.controller.access.Action;
import org.jboss.as.controller.access.AuthorizationResult;
Expand Down Expand Up @@ -81,6 +82,7 @@
import org.jboss.staxmapper.XMLElementReader;
import org.jboss.staxmapper.XMLElementWriter;
import org.jboss.staxmapper.XMLMapper;
import org.wildfly.common.Assert;
import org.wildfly.common.function.Functions;
import org.wildfly.security.auth.server.SecurityIdentity;

Expand Down Expand Up @@ -361,7 +363,23 @@ public void initializeParsers(final Extension extension, final String moduleName
*
* @return the {@link ExtensionContext}. Will not return {@code null}
*/
@Deprecated(forRemoval = true)
public ExtensionContext getExtensionContext(final String moduleName, ManagementResourceRegistration rootRegistration, ExtensionRegistryType extensionRegistryType) {
return this.getExtensionContext(moduleName, Stability.DEFAULT, rootRegistration, extensionRegistryType);
}

/**
* Gets an {@link ExtensionContext} for use when handling an {@code add} operation for
* a resource representing an {@link org.jboss.as.controller.Extension}.
*
* @param moduleName the name of the extension's module. Cannot be {@code null}
* @param stability the stability of the extension
* @param rootRegistration the root management resource registration
* @param extensionRegistryType the type of registry we are working on, which has an effect on things like whether extensions get registered etc.
*
* @return the {@link ExtensionContext}. Will not return {@code null}
*/
public ExtensionContext getExtensionContext(final String moduleName, Stability stability, ManagementResourceRegistration rootRegistration, ExtensionRegistryType extensionRegistryType) {
// Can't use processType.isServer() to determine where to look for profile reg because a lot of test infrastructure
// doesn't add the profile mrr even in HC-based tests
ManagementResourceRegistration profileRegistration = rootRegistration.getSubModel(PathAddress.pathAddress(PathElement.pathElement(PROFILE)));
Expand All @@ -373,7 +391,7 @@ public ExtensionContext getExtensionContext(final String moduleName, ManagementR
// Hack to restrict extra data to specified extension(s)
boolean allowSupplement = legallySupplemented.contains(moduleName);
ManagedAuditLogger al = allowSupplement ? auditLogger : null;
return new ExtensionContextImpl(moduleName, profileRegistration, deploymentsRegistration, pathManager, extensionRegistryType, al, this.stability);
return new ExtensionContextImpl(moduleName, stability, profileRegistration, deploymentsRegistration, pathManager, extensionRegistryType, al);
}

public Set<ProfileParsingCompletionHandler> getProfileParsingCompletionHandlers() {
Expand Down Expand Up @@ -638,11 +656,11 @@ private class ExtensionContextImpl implements ExtensionContext, ExtensionContext
private final ManagementResourceRegistration profileRegistration;
private final ManagementResourceRegistration deploymentsRegistration;
private final ExtensionRegistryType extensionRegistryType;
private final Stability stability;
private final Stability stability; // stability of extension

private ExtensionContextImpl(String extensionName, ManagementResourceRegistration profileResourceRegistration,
private ExtensionContextImpl(String extensionName, Stability stability, ManagementResourceRegistration profileResourceRegistration,
ManagementResourceRegistration deploymentsResourceRegistration, PathManager pathManager,
ExtensionRegistryType extensionRegistryType, ManagedAuditLogger auditLogger, Stability stability) {
ExtensionRegistryType extensionRegistryType, ManagedAuditLogger auditLogger) {
assert pathManager != null || !processType.isServer() : "pathManager is null";
this.pathManager = pathManager;
this.extension = getExtensionInfo(extensionName);
Expand Down Expand Up @@ -678,8 +696,8 @@ public SubsystemRegistration registerSubsystem(String name, ModelVersion version
if (deprecated){
ControllerLogger.DEPRECATED_LOGGER.extensionDeprecated(name);
}
SubsystemRegistrationImpl result = new SubsystemRegistrationImpl(name, version,
profileRegistration, deploymentsRegistration, extensionRegistryType, extension.extensionModuleName, processType, stability);
SubsystemRegistrationImpl result = new SubsystemRegistrationImpl(name, version, this.stability,
profileRegistration, deploymentsRegistration, extensionRegistryType, extension.extensionModuleName, processType);
if (registerTransformers){
transformerRegistry.loadAndRegisterTransformers(name, version, extension.extensionModuleName);
}
Expand Down Expand Up @@ -715,7 +733,7 @@ public ProcessType getProcessType() {

@Override
public Stability getStability() {
return this.stability;
return this.profileRegistration.getStability();
}

@Override
Expand Down Expand Up @@ -835,17 +853,17 @@ private class SubsystemRegistrationImpl implements SubsystemRegistration {
private final String extensionModuleName;
private volatile boolean hostCapable;

private SubsystemRegistrationImpl(String name, ModelVersion version,
private SubsystemRegistrationImpl(String name, ModelVersion version, Stability stability,
ManagementResourceRegistration profileRegistration,
ManagementResourceRegistration deploymentsRegistration,
ExtensionRegistryType extensionRegistryType,
String extensionModuleName,
ProcessType processType, Stability stability) {
ProcessType processType) {
assert profileRegistration != null;
this.name = name;
this.profileRegistration = profileRegistration;
if (deploymentsRegistration == null){
this.deploymentsRegistration = ManagementResourceRegistration.Factory.forProcessType(processType, stability).createRegistration(new SimpleResourceDefinition(null, NonResolvingResourceDescriptionResolver.INSTANCE));
this.deploymentsRegistration = ManagementResourceRegistration.Factory.forProcessType(processType, this.profileRegistration.getStability()).createRegistration(ResourceDefinition.builder(ResourceRegistration.of(null, this.profileRegistration.getStability()), NonResolvingResourceDescriptionResolver.INSTANCE).build());
}else {
this.deploymentsRegistration = deploymentsRegistration;
}
Expand All @@ -860,22 +878,37 @@ public Stability getStability() {
return this.stability;
}

@Override
public <F extends Feature> boolean enables(F feature) {
return this.profileRegistration.enables(feature);
}

@Override
public void setHostCapable() {
hostCapable = true;
}

@Override
public ManagementResourceRegistration registerSubsystemModel(ResourceDefinition resourceDefinition) {
assert resourceDefinition != null : "resourceDefinition is null";
checkHostCapable();
return profileRegistration.registerSubModel(resourceDefinition);
return this.register(this.profileRegistration, resourceDefinition);
}

@Override
public ManagementResourceRegistration registerDeploymentModel(ResourceDefinition resourceDefinition) {
assert resourceDefinition != null : "resourceDefinition is null";
return deploymentsRegistration.registerSubModel(resourceDefinition);
return this.register(this.deploymentsRegistration, resourceDefinition);
}

private ManagementResourceRegistration register(ManagementResourceRegistration parent, ResourceDefinition definition) {
Assert.checkNotNullParam("definition", definition);
Stability childStability = definition.getStability();
// Propagate parent stability-level to child, if necessary
return parent.registerSubModel((childStability != this.stability) && !childStability.enables(this.stability) ? new ProvidedResourceDefinition(definition) {
@Override
public Stability getStability() {
return SubsystemRegistrationImpl.this.stability;
}
} : definition);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.jboss.as.controller.operations.validation.IntRangeValidator;
import org.jboss.as.controller.operations.validation.StringLengthValidator;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.as.version.Stability;
import org.jboss.dmr.ModelType;

/**
Expand Down Expand Up @@ -54,8 +55,15 @@ public class ExtensionSubsystemResourceDefinition extends SimpleResourceDefiniti
.setRuntimeServiceNotRequired()
.build();

private final Stability stability;

ExtensionSubsystemResourceDefinition() {
this(Stability.DEFAULT);
}

ExtensionSubsystemResourceDefinition(Stability stability) {
super(new Parameters(PathElement.pathElement(SUBSYSTEM), ControllerResolver.getResolver(EXTENSION, SUBSYSTEM)).setRuntime());
this.stability = stability;
}

@Override
Expand All @@ -65,4 +73,9 @@ public void registerAttributes(ManagementResourceRegistration resourceRegistrati
resourceRegistration.registerReadOnlyAttribute(MICRO_VERSION, null);
resourceRegistration.registerReadOnlyAttribute(XML_NAMESPACES, null);
}

@Override
public Stability getStability() {
return this.stability;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.ParsedBootOp;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.operations.common.Util;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.dmr.ModelNode;
Expand Down Expand Up @@ -81,7 +82,7 @@ public void execute(OperationContext context, ModelNode operation) throws Operat
for (ParsedBootOp op : extensionAdds) {
String module = op.address.getLastElement().getValue();
ExtensionAddHandler addHandler = ExtensionAddHandler.class.cast(op.handler);
Future<OperationFailedRuntimeException> future = executor.submit(new ExtensionInitializeTask(module, addHandler, rootResourceRegistration));
Future<OperationFailedRuntimeException> future = executor.submit(new ExtensionInitializeTask(module, addHandler, rootResourceRegistration, op.getAddress()));
futures.put(module, future);
}

Expand Down Expand Up @@ -112,19 +113,21 @@ private static class ExtensionInitializeTask implements Callable<OperationFailed
private final String module;
private final ExtensionAddHandler addHandler;
private final ManagementResourceRegistration rootResourceRegistration;
private final PathAddress address;

public ExtensionInitializeTask(String module, ExtensionAddHandler addHandler,
ManagementResourceRegistration rootResourceRegistration) {
ManagementResourceRegistration rootResourceRegistration, PathAddress address) {
this.module = module;
this.addHandler = addHandler;
this.rootResourceRegistration = rootResourceRegistration;
this.address = address;
}

@Override
public OperationFailedRuntimeException call() {
OperationFailedRuntimeException failure = null;
try {
addHandler.initializeExtension(module, rootResourceRegistration);
addHandler.initializeExtension(module, rootResourceRegistration, this.address);
} catch (OperationFailedRuntimeException e) {
failure = e;
}
Expand Down

0 comments on commit 15ea126

Please sign in to comment.