Skip to content

Commit

Permalink
Merge pull request #5902 from pferraro/WFCORE-6742
Browse files Browse the repository at this point in the history
WFCORE-6742 SubsystemExtension needs the ability to define the current model/schema version given the stability level of the process
  • Loading branch information
yersan authored Mar 18, 2024
2 parents e384985 + 3fc0e7c commit bce0ca6
Show file tree
Hide file tree
Showing 9 changed files with 419 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,21 +110,24 @@ static void initializeExtension(ExtensionRegistry extensionRegistry, String modu
}
while (extensions.hasNext()) {
Extension extension = extensions.next();
if (extensionRegistry.enables(extension)) {
ClassLoader oldTccl = WildFlySecurityManager.setCurrentContextClassLoaderPrivileged(extension.getClass());
try {
if (unknownModule || !extensionRegistry.getExtensionModuleNames().contains(module)) {
// This extension wasn't handled by the standalone.xml or domain.xml parsing logic, so we
// need to initialize its parsers so we can display what XML namespaces it supports
extensionRegistry.initializeParsers(extension, module, null);
// AS7-6190 - ensure we initialize parsers for other extensions from this module
// now that we know the registry was unaware of the module
unknownModule = true;
}
ClassLoader oldTccl = WildFlySecurityManager.setCurrentContextClassLoaderPrivileged(extension.getClass());
try {
if (unknownModule || !extensionRegistry.getExtensionModuleNames().contains(module)) {
// This extension wasn't handled by the standalone.xml or domain.xml parsing logic, so we
// need to initialize its parsers so we can display what XML namespaces it supports
extensionRegistry.initializeParsers(extension, module, null);
// AS7-6190 - ensure we initialize parsers for other extensions from this module
// now that we know the registry was unaware of the module
unknownModule = true;
}
// If extension is not enabled by stability level of process, skip model registration
if (extensionRegistry.enables(extension)) {
extension.initialize(extensionRegistry.getExtensionContext(module, extension.getStability(), rootRegistration, extensionRegistryType));
} finally {
WildFlySecurityManager.setCurrentContextClassLoaderPrivileged(oldTccl);
} else {
ControllerLogger.ROOT_LOGGER.unstableExtension(extension.getClass().getName(), module);
}
} finally {
WildFlySecurityManager.setCurrentContextClassLoaderPrivileged(oldTccl);
}
}
} catch (ModuleNotFoundException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,9 @@ public ExtensionParsingContext getExtensionParsingContext(final String moduleNam
* be any actual parsing (e.g. in a slave Host Controller or in a server in a managed domain)
*/
public void initializeParsers(final Extension extension, final String moduleName, final XMLMapper xmlMapper) {
ExtensionParsingContextImpl parsingContext = new ExtensionParsingContextImpl(moduleName, xmlMapper);
extension.initializeParsers(parsingContext);
parsingContext.attemptCurrentParserInitialization();
try (AbstractExtensionParsingContext context = this.enables(extension) ? new ExtensionParsingContextImpl(moduleName, xmlMapper) : new UnstableExtensionParsingContext(moduleName, xmlMapper)) {
extension.initializeParsers(context);
}
}

/**
Expand Down Expand Up @@ -542,30 +542,25 @@ public Stability getStability() {
return this.stability;
}

private class ExtensionParsingContextImpl implements ExtensionParsingContext {

private final ExtensionInfo extension;
private boolean hasNonSupplierParser;
private String latestNamespace;
private Supplier<XMLElementReader<List<ModelNode>>> latestSupplier;
private abstract class AbstractExtensionParsingContext implements ExtensionParsingContext, AutoCloseable {
final ExtensionInfo extension;

private ExtensionParsingContextImpl(String extensionName, XMLMapper xmlMapper) {
extension = getExtensionInfo(extensionName);
AbstractExtensionParsingContext(String extensionName, XMLMapper xmlMapper) {
this.extension = ExtensionRegistry.this.getExtensionInfo(extensionName);
if (xmlMapper != null) {
synchronized (extension) {
extension.xmlMapper = xmlMapper;
synchronized (this.extension) {
this.extension.xmlMapper = xmlMapper;
}
}
}

@Override
public ProcessType getProcessType() {
return processType;
return ExtensionRegistry.this.processType;
}

@Override
public RunningMode getRunningMode() {
return runningModeControl.getRunningMode();
return ExtensionRegistry.this.runningModeControl.getRunningMode();
}

@Override
Expand All @@ -578,6 +573,22 @@ public <F extends Feature> boolean enables(F feature) {
return ExtensionRegistry.this.enables(feature);
}

@Override
public void close() {
// Do nothing
}
}

private class ExtensionParsingContextImpl extends AbstractExtensionParsingContext {

private boolean hasNonSupplierParser;
private String latestNamespace;
private Supplier<XMLElementReader<List<ModelNode>>> latestSupplier;

ExtensionParsingContextImpl(String extensionName, XMLMapper xmlMapper) {
super(extensionName, xmlMapper);
}

@Override
public void setSubsystemXmlMapping(String subsystemName, String namespaceUri, XMLElementReader<List<ModelNode>> reader) {
assert subsystemName != null : "subsystemName is null";
Expand Down Expand Up @@ -618,7 +629,8 @@ public void setProfileParsingCompletionHandler(ProfileParsingCompletionHandler h
}
}

private void attemptCurrentParserInitialization() {
@Override
public void close() {
if (ExtensionRegistry.this.processType != ProcessType.DOMAIN_SERVER
&& !hasNonSupplierParser && latestSupplier != null) {
// We've only been passed suppliers for parsers, which means the model
Expand All @@ -645,6 +657,37 @@ private void preCacheParserDescription(XMLElementReader<List<ModelNode>> reader)
}
}

private class UnstableExtensionParsingContext extends AbstractExtensionParsingContext {

UnstableExtensionParsingContext(String extensionName, XMLMapper xmlMapper) {
super(extensionName, xmlMapper);
}

@Override
public void setSubsystemXmlMapping(String subsystemName, String namespaceUri, XMLElementReader<List<ModelNode>> reader) {
this.setSubsystemXMLMapping(subsystemName, namespaceUri);
}

@Override
public void setSubsystemXmlMapping(String subsystemName, String namespaceUri, Supplier<XMLElementReader<List<ModelNode>>> supplier) {
this.setSubsystemXMLMapping(subsystemName, namespaceUri);
}

private void setSubsystemXMLMapping(String subsystemName, String namespaceUri) {
synchronized (this.extension) {
this.extension.getSubsystemInfo(subsystemName).addParsingNamespace(namespaceUri);
if (this.extension.xmlMapper != null) {
this.extension.xmlMapper.registerRootElement(new QName(namespaceUri, SUBSYSTEM), new UnstableSubsystemNamespaceParser(subsystemName));
}
}
}

@Override
public void setProfileParsingCompletionHandler(ProfileParsingCompletionHandler handler) {
// Ignore
}
}

@SuppressWarnings("deprecation")
private class ExtensionContextImpl implements ExtensionContext, ExtensionContextSupplement {

Expand Down Expand Up @@ -733,7 +776,7 @@ public ProcessType getProcessType() {

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

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/

package org.jboss.as.controller.extension;

import java.util.List;

import javax.xml.stream.XMLStreamException;

import org.jboss.as.controller.logging.ControllerLogger;
import org.jboss.dmr.ModelNode;
import org.jboss.staxmapper.XMLElementReader;
import org.jboss.staxmapper.XMLExtendedStreamReader;

/**
* A placeholder parser for a subsystem namespace not enabled by the stability level of the current process.
*/
public class UnstableSubsystemNamespaceParser implements XMLElementReader<List<ModelNode>> {
private final String subsystemName;

public UnstableSubsystemNamespaceParser(String subsystemName) {
this.subsystemName = subsystemName;
}

@Override
public void readElement(XMLExtendedStreamReader reader, List<ModelNode> value) throws XMLStreamException {
throw ControllerLogger.ROOT_LOGGER.unstableSubsystemNamespace(this.subsystemName, reader.getNamespaceURI());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3752,4 +3752,11 @@ OperationFailedRuntimeException capabilityAlreadyRegisteredInContext(String capa

@Message(id = 504, value = "The operation %s is not defined for resource %s.")
UnsupportedOperationException missingOperationForResource(String op, String address);

@Message(id = 505, value = "%s subsystem namespace %s is not enabled by the current stability level")
XMLStreamException unstableSubsystemNamespace(String subsystemName, String namespaceURI);

@LogMessage(level = WARN)
@Message(id = 506, value = "Extension %s from module %s is not enabled by the current stability level")
void unstableExtension(String extensionName, String moduleName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.jboss.as.controller.ProcessType;
import org.jboss.as.controller.RunningMode;
import org.jboss.as.controller.SubsystemSchema;
import org.jboss.as.controller.extension.UnstableSubsystemNamespaceParser;
import org.jboss.dmr.ModelNode;
import org.jboss.staxmapper.XMLElementReader;

Expand Down Expand Up @@ -81,9 +82,8 @@ public interface ExtensionParsingContext extends FeatureRegistry {
*/
default <S extends SubsystemSchema<S>> void setSubsystemXmlMappings(String subsystemName, Set<S> schemas) {
for (S schema : schemas) {
if (this.enables(schema)) {
this.setSubsystemXmlMapping(subsystemName, schema.getNamespace().getUri(), schema);
}
XMLElementReader<List<ModelNode>> reader = this.enables(schema) ? schema : new UnstableSubsystemNamespaceParser(subsystemName);
this.setSubsystemXmlMapping(subsystemName, schema.getNamespace().getUri(), reader);
}
}

Expand Down
Loading

0 comments on commit bce0ca6

Please sign in to comment.