Skip to content

Commit

Permalink
Merge pull request #5829 from pferraro/WFCORE-6176
Browse files Browse the repository at this point in the history
WFCORE-6176 Generalize capability filter to cover more complex scenarios.
  • Loading branch information
bstansberry authored Jan 18, 2024
2 parents b949ad7 + 07ea52e commit 14a6d1f
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.capability.RuntimeCapability;
Expand All @@ -29,7 +30,6 @@
import org.jboss.as.controller.registry.OperationEntry;
import org.jboss.as.controller.registry.Resource;
import org.jboss.as.server.DeploymentProcessorTarget;
import org.jboss.dmr.ModelNode;
import org.wildfly.common.iteration.CompositeIterable;
import org.wildfly.subsystem.resource.capability.ResourceCapabilityReferenceRecorder;
import org.wildfly.subsystem.resource.operation.AddResourceOperationStepHandlerDescriptor;
Expand Down Expand Up @@ -139,9 +139,11 @@ default OperationEntry.Flag getRemoveOperationRestartFlag() {
* Default {@link ResourceDescriptor} implementation.
*/
class DefaultResourceDescriptor implements ResourceDescriptor {
static final BiPredicate<OperationContext, Resource> DISABLED_CAPABILITY = (context, resource) -> false;

private final ResourceDescriptionResolver descriptionResolver;
private final Optional<ResourceOperationRuntimeHandler> runtimeHandler;
private final Map<RuntimeCapability<?>, Predicate<ModelNode>> capabilities;
private final Map<RuntimeCapability<?>, BiPredicate<OperationContext, Resource>> capabilities;
private final Map<AttributeDefinition, OperationStepHandler> readWriteAttributes = new HashMap<>();
private final Iterable<? extends AttributeDefinition> readOnlyAttributes;
private final Set<PathElement> requiredChildren;
Expand Down Expand Up @@ -170,7 +172,7 @@ class DefaultResourceDescriptor implements ResourceDescriptor {
if (!modelOnlyAttributes.isEmpty()) {
OperationStepHandlerDescriptor descriptor = new OperationStepHandlerDescriptor() {
@Override
public Predicate<ModelNode> getCapabilityFilter(RuntimeCapability<?> capability) {
public BiPredicate<OperationContext, Resource> getCapabilityFilter(RuntimeCapability<?> capability) {
return DefaultResourceDescriptor.this.getCapabilityFilter(capability);
}
};
Expand Down Expand Up @@ -209,8 +211,8 @@ public Set<RuntimeCapability<?>> getCapabilities() {
}

@Override
public Predicate<ModelNode> getCapabilityFilter(RuntimeCapability<?> capability) {
return this.capabilities.getOrDefault(capability, model -> false);
public BiPredicate<OperationContext, Resource> getCapabilityFilter(RuntimeCapability<?> capability) {
return this.capabilities.getOrDefault(capability, DISABLED_CAPABILITY);
}

@Override
Expand Down Expand Up @@ -353,7 +355,7 @@ default C renameAttribute(AttributeDefinition attribute, AttributeDefinition tar
* @return a reference to this configurator
*/
default C addCapability(RuntimeCapability<?> capability) {
return this.addCapability(capability, ModelNode::isDefined);
return this.addCapability(capability, AbstractConfigurator.DEFAULT_CAPABILITY_FILTER);
}

/**
Expand All @@ -362,15 +364,15 @@ default C addCapability(RuntimeCapability<?> capability) {
* @param filter a predicate used to determine when the specified capability should be registered
* @return a reference to this configurator
*/
C addCapability(RuntimeCapability<?> capability, Predicate<ModelNode> filter);
C addCapability(RuntimeCapability<?> capability, BiPredicate<OperationContext, Resource> filter);

/**
* Adds the specified runtime capabilities to this resource.
* @param capabilities a collection of runtime capabilities
* @return a reference to this configurator
*/
default C addCapabilities(Collection<RuntimeCapability<?>> capabilities) {
return this.addCapabilities(capabilities, ModelNode::isDefined);
return this.addCapabilities(capabilities, AbstractConfigurator.DEFAULT_CAPABILITY_FILTER);
}

/**
Expand All @@ -379,7 +381,7 @@ default C addCapabilities(Collection<RuntimeCapability<?>> capabilities) {
* @param filter a predicate used to determine when the specified capability should be registered
* @return a reference to this configurator
*/
C addCapabilities(Collection<RuntimeCapability<?>> capabilities, Predicate<ModelNode> filter);
C addCapabilities(Collection<RuntimeCapability<?>> capabilities, BiPredicate<OperationContext, Resource> filter);

/**
* Defines a required child of this resource. Required children will be automatically added, if no child resource exists with the specified path.
Expand Down Expand Up @@ -484,7 +486,7 @@ default C addResourceCapabilityReference(ResourceCapabilityReferenceRecorder<?>
* @return a reference to this configurator
*/
default <P extends Supplier<RuntimeCapability<?>>> C provideCapabilities(Collection<P> providers) {
return this.provideCapabilities(providers, ModelNode::isDefined);
return this.provideCapabilities(providers, AbstractConfigurator.DEFAULT_CAPABILITY_FILTER);
}

/**
Expand All @@ -493,7 +495,7 @@ default <P extends Supplier<RuntimeCapability<?>>> C provideCapabilities(Collect
* @param filter a predicate used to determine when the specified capability should be registered
* @return a reference to this configurator
*/
<P extends Supplier<RuntimeCapability<?>>> C provideCapabilities(Collection<P> providers, Predicate<ModelNode> filter);
<P extends Supplier<RuntimeCapability<?>>> C provideCapabilities(Collection<P> providers, BiPredicate<OperationContext, Resource> filter);

/**
* Defines a set of required children of this resource. Required children will be automatically added, if no child resource exists with the specified path.
Expand Down Expand Up @@ -525,15 +527,15 @@ interface Builder extends Configurator<Builder> {
* An abstract {@link ResourceDescriptor} configurator.
*/
abstract static class AbstractConfigurator<C extends Configurator<C>> implements Configurator<C> {
static final Predicate<ModelNode> DEFAULT_CAPABILITY_PREDICATE = ModelNode::isDefined;
static final BiPredicate<OperationContext, Resource> DEFAULT_CAPABILITY_FILTER = (context, resource) -> resource.getModel().isDefined();

private static final Set<OperationEntry.Flag> RESTART_FLAGS = EnumSet.of(OperationEntry.Flag.RESTART_ALL_SERVICES, OperationEntry.Flag.RESTART_JVM, OperationEntry.Flag.RESTART_NONE, OperationEntry.Flag.RESTART_RESOURCE_SERVICES);

private final ResourceDescriptionResolver descriptionResolver;
private Optional<ResourceOperationRuntimeHandler> runtimeHandler = Optional.empty();
private OperationEntry.Flag addOperationRestartFlag = OperationEntry.Flag.RESTART_NONE;
private OperationEntry.Flag removeOperationRestartFlag = OperationEntry.Flag.RESTART_NONE;
private Map<RuntimeCapability<?>, Predicate<ModelNode>> capabilities = Map.of();
private Map<RuntimeCapability<?>, BiPredicate<OperationContext, Resource>> capabilities = Map.of();
private Collection<AttributeDefinition> attributes = List.of();
private Collection<AttributeDefinition> modelOnlyAttributes = List.of();
private Collection<AttributeDefinition> readOnlyAttributes = List.of();
Expand Down Expand Up @@ -612,13 +614,13 @@ public C translateAttribute(AttributeDefinition attribute, AttributeTranslation
}

@Override
public C addCapability(RuntimeCapability<?> capability, Predicate<ModelNode> filter) {
public C addCapability(RuntimeCapability<?> capability, BiPredicate<OperationContext, Resource> filter) {
this.capabilities = concat(this.capabilities, capability, filter);
return this.self();
}

@Override
public C addCapabilities(Collection<RuntimeCapability<?>> capabilities, Predicate<ModelNode> filter) {
public C addCapabilities(Collection<RuntimeCapability<?>> capabilities, BiPredicate<OperationContext, Resource> filter) {
this.capabilities = concat(this.capabilities, capabilities.stream(), filter);
return this.self();
}
Expand Down Expand Up @@ -687,7 +689,7 @@ public <P extends Supplier<AttributeDefinition>> C provideReadOnlyAttributes(Col
}

@Override
public <P extends Supplier<RuntimeCapability<?>>> C provideCapabilities(Collection<P> providers, Predicate<ModelNode> filter) {
public <P extends Supplier<RuntimeCapability<?>>> C provideCapabilities(Collection<P> providers, BiPredicate<OperationContext, Resource> filter) {
this.capabilities = concat(this.capabilities, stream(providers), filter);
return this.self();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ protected void recordCapabilitiesAndRequirements(OperationContext context, Model

for (RuntimeCapability<?> capability : registration.getCapabilities()) {
// Only register capabilities when allowed by the associated predicate
if (this.descriptor.getCapabilityFilter(capability).test(model)) {
if (this.descriptor.getCapabilityFilter(capability).test(context, resource)) {
context.registerCapability(capability.isDynamicallyNamed() ? capability.fromBaseCapability(address) : capability);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
package org.wildfly.subsystem.resource.operation;

import java.util.Optional;
import java.util.function.Predicate;
import java.util.function.BiPredicate;

import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.dmr.ModelNode;
import org.jboss.as.controller.registry.Resource;

/**
* Describes common properties of all operation handlers of a resource.
Expand All @@ -29,7 +30,7 @@ default Optional<ResourceOperationRuntimeHandler> getRuntimeHandler() {
* @param capability a runtime capability
* @return a resource model predicate
*/
default Predicate<ModelNode> getCapabilityFilter(RuntimeCapability<?> capability) {
return ModelNode::isDefined;
default BiPredicate<OperationContext, Resource> getCapabilityFilter(RuntimeCapability<?> capability) {
return (context, resource) -> resource.getModel().isDefined();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ protected void performRemove(OperationContext context, ModelNode operation, Mode

for (RuntimeCapability<?> capability : registration.getCapabilities()) {
// Only register capabilities when allowed by the associated predicate
if (this.descriptor.getCapabilityFilter(capability).test(model)) {
if (this.descriptor.getCapabilityFilter(capability).test(context, resource)) {
context.deregisterCapability((capability.isDynamicallyNamed() ? capability.fromBaseCapability(address) : capability).getName());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
package org.wildfly.subsystem.resource.operation;

import java.util.function.Predicate;
import java.util.function.BiPredicate;

import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.OperationContext;
Expand Down Expand Up @@ -39,15 +39,15 @@ protected void recordCapabilitiesAndRequirements(OperationContext context, Attri
PathAddress address = context.getCurrentAddress();
Resource resource = context.readResource(PathAddress.EMPTY_ADDRESS);
// newValue is already applied to the model
ModelNode newModel = resource.getModel();
ModelNode oldModel = newModel.clone();
oldModel.get(attribute.getName()).set(oldValue);
// Clone resource and fabricate old state
Resource oldResource = resource.clone();
oldResource.getModel().get(attribute.getName()).set(oldValue);

ImmutableManagementResourceRegistration registration = context.getResourceRegistration();
for (RuntimeCapability<?> capability : registration.getCapabilities()) {
Predicate<ModelNode> predicate = this.descriptor.getCapabilityFilter(capability);
boolean registered = predicate.test(oldModel);
boolean shouldRegister = predicate.test(newModel);
BiPredicate<OperationContext, Resource> predicate = this.descriptor.getCapabilityFilter(capability);
boolean registered = predicate.test(context, oldResource);
boolean shouldRegister = predicate.test(context, resource);

if (!registered && shouldRegister) {
// Attribute change enables capability registration
Expand Down

0 comments on commit 14a6d1f

Please sign in to comment.