Skip to content

Commit

Permalink
Merge pull request #5823 from pferraro/main
Browse files Browse the repository at this point in the history
WFCORE-6347 Misc API cleanup of capability reference recorder interfaces in wildfly-subsystem
  • Loading branch information
pferraro authored Jan 6, 2024
2 parents df80b7d + 663feff commit 1157824
Show file tree
Hide file tree
Showing 7 changed files with 611 additions and 195 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ public String[] apply(PathAddress address) {
return new String[] { grandparent.getParent().getLastElement().getValue(), grandparent.getLastElement().getValue() };
}
},
;
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ public String[] apply(PathAddress address) {
return new String[] { ModelDescriptionConstants.LOCAL };
}
},
;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class AggregateDiscoveryProviderRegistrar extends DiscoveryProviderRegist
static final PathElement PATH = PathElement.pathElement("aggregate-provider");

static final StringListAttributeDefinition PROVIDER_NAMES = new StringListAttributeDefinition.Builder("providers")
.setCapabilityReference(CapabilityReferenceRecorder.of(DISCOVERY_PROVIDER_CAPABILITY, DISCOVERY_PROVIDER_DESCRIPTOR))
.setCapabilityReference(CapabilityReferenceRecorder.builder(DISCOVERY_PROVIDER_CAPABILITY, DISCOVERY_PROVIDER_DESCRIPTOR).build())
.setFlags(Flag.RESTART_RESOURCE_SERVICES)
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,15 +364,6 @@ default C addCapability(RuntimeCapability<?> capability) {
*/
C addCapability(RuntimeCapability<?> capability, Predicate<ModelNode> filter);

/**
* Adds the specified runtime capabilities to this resource.
* @param capabilities a variable number of runtime capabilities
* @return a reference to this configurator
*/
default C addCapabilities(RuntimeCapability<?>... capabilities) {
return this.addCapabilities(Set.of(capabilities));
}

/**
* Adds the specified runtime capabilities to this resource.
* @param capabilities a collection of runtime capabilities
Expand Down Expand Up @@ -431,15 +422,6 @@ default C addResourceCapabilityReference(ResourceCapabilityReferenceRecorder<?>
return this.addResourceCapabilityReferences(Set.of(reference));
}

/**
* Adds a number of capability references that records requirements for this resource.
* @param references a variable number of capability reference recorders
* @return a reference to this configurator
*/
default C addResourceCapabilityReferences(ResourceCapabilityReferenceRecorder<?>... references) {
return this.addResourceCapabilityReferences(Set.of(references));
}

/**
* Adds a number of capability references that records requirements for this resource.
* @param references a collection of capability reference recorders
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.capability.BinaryCapabilityNameResolver;
import org.jboss.as.controller.capability.QuaternaryCapabilityNameResolver;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.controller.capability.TernaryCapabilityNameResolver;
import org.jboss.as.controller.capability.UnaryCapabilityNameResolver;
import org.jboss.as.controller.registry.Resource;
import org.jboss.dmr.ModelNode;
import org.wildfly.service.descriptor.BinaryServiceDescriptor;
import org.wildfly.service.descriptor.NullaryServiceDescriptor;
import org.wildfly.service.descriptor.QuaternaryServiceDescriptor;
import org.wildfly.service.descriptor.ServiceDescriptor;
import org.wildfly.service.descriptor.TernaryServiceDescriptor;
import org.wildfly.service.descriptor.UnaryServiceDescriptor;
Expand Down Expand Up @@ -61,62 +63,102 @@ default void removeCapabilityRequirements(OperationContext context, Resource res
}

/**
* Creates a new reference between the specified capability and the specified requirement.
* Creates a builder for a new reference between the specified capability and the specified requirement.
* @param capability the capability referencing the specified requirement
* @param requirement the requirement of the specified capability
*/
static <T> Builder<T> builder(RuntimeCapability<Void> capability, NullaryServiceDescriptor<T> requirement) {
return new Builder<>(capability, requirement, ResourceCapabilityServiceDescriptorReference.EMPTY_RESOLVER);
return new DefaultBuilder<>(capability, requirement, ResourceCapabilityServiceDescriptorReference.EMPTY_RESOLVER);
}

/**
* Creates a new reference between the specified capability and the specified requirement.
* Creates a builder for a new reference between the specified capability and the specified requirement.
* By default, the requirement name will resolve against the path of the current resource.
* @param capability the capability referencing the specified requirement
* @param requirement the requirement of the specified capability
*/
static <T> NaryBuilder<T> builder(RuntimeCapability<Void> capability, UnaryServiceDescriptor<T> requirement) {
return new DefaultBuilder<>(capability, requirement, UnaryCapabilityNameResolver.DEFAULT);
}

/**
* Creates a builder for a new reference between the specified capability and the specified requirement.
* By default, the requirement name will resolve against the paths of the parent and current resources, respectively.
* @param capability the capability referencing the specified requirement
* @param requirement the requirement of the specified capability
* @param requirementNameResolver function for resolving the dynamic components of the requirement name
*/
static <T> Builder<T> builder(RuntimeCapability<Void> capability, UnaryServiceDescriptor<T> requirement, UnaryCapabilityNameResolver requirementNameResolver) {
return new Builder<>(capability, requirement, requirementNameResolver);
static <T> NaryBuilder<T> builder(RuntimeCapability<Void> capability, BinaryServiceDescriptor<T> requirement) {
return new DefaultBuilder<>(capability, requirement, BinaryCapabilityNameResolver.PARENT_CHILD);
}

/**
* Creates a new reference between the specified capability and the specified requirement.
* Creates a builder for a new reference between the specified capability and the specified requirement.
* By default, the requirement name will resolve against the paths of the grandparent, parent, and current resources, respectively.
* @param capability the capability referencing the specified requirement
* @param requirement the requirement of the specified capability
* @param requirementNameResolver function for resolving the dynamic components of the requirement name
*/
static <T> Builder<T> builder(RuntimeCapability<Void> capability, BinaryServiceDescriptor<T> requirement, BinaryCapabilityNameResolver requirementNameResolver) {
return new Builder<>(capability, requirement, requirementNameResolver);
static <T> NaryBuilder<T> builder(RuntimeCapability<Void> capability, TernaryServiceDescriptor<T> requirement) {
return new DefaultBuilder<>(capability, requirement, TernaryCapabilityNameResolver.GRANDPARENT_PARENT_CHILD);
}

/**
* Creates a new reference between the specified capability and the specified requirement.
* Creates a builder for a new reference between the specified capability and the specified requirement.
* By default, the requirement name will resolve against the paths of the great-grandparent, grandparent, parent, and current resources, respectively.
* @param capability the capability referencing the specified requirement
* @param requirement the requirement of the specified capability
* @param requirementNameResolver function for resolving the dynamic components of the requirement name
*/
static <T> Builder<T> builder(RuntimeCapability<Void> capability, TernaryServiceDescriptor<T> requirement, TernaryCapabilityNameResolver requirementNameResolver) {
return new Builder<>(capability, requirement, requirementNameResolver);
static <T> NaryBuilder<T> builder(RuntimeCapability<Void> capability, QuaternaryServiceDescriptor<T> requirement) {
return new DefaultBuilder<>(capability, requirement, QuaternaryCapabilityNameResolver.GREATGRANDPARENT_GRANDPARENT_PARENT_CHILD);
}

interface Builder<T> {
/**
* Only reference the provided capability if value of the specified attribute complies with the specified predicate.
* @param attribute an attribute of the resource to use for conditional registration
* @param predicate conditionally determines whether to require this capability, depending on the resolve value of the specified attribute
* @return a reference to this builder
*/
Builder<T> when(AttributeDefinition attribute, Predicate<ModelNode> predicate);

/**
* Builds the configured capability reference recorder.
* @return a capability reference recorder
*/
org.wildfly.subsystem.resource.capability.ResourceCapabilityReferenceRecorder<T> build();
}

static class Builder<T> {
interface NaryBuilder<T> extends Builder<T> {
/**
* Overrides the default requirement name resolver.
* @param requirementNameResolver a capability name resolver
* @return a reference to this builder
*/
Builder<T> withRequirementNameResolver(Function<PathAddress, String[]> requirementNameResolver);
}

static class DefaultBuilder<T> implements NaryBuilder<T> {
private final RuntimeCapability<Void> capability;
private final ServiceDescriptor<T> requirement;
private final Function<PathAddress, String[]> requirementNameResolver;

private Function<PathAddress, String[]> requirementNameResolver;
private BiPredicate<OperationContext, Resource> predicate = ResourceCapabilityServiceDescriptorReference.ALWAYS;

Builder(RuntimeCapability<Void> capability, ServiceDescriptor<T> requirement, Function<PathAddress, String[]> requirementNameResolver) {
DefaultBuilder(RuntimeCapability<Void> capability, ServiceDescriptor<T> requirement, Function<PathAddress, String[]> defaultRequirementNameResolver) {
this.capability = capability;
this.requirement = requirement;
this.requirementNameResolver = defaultRequirementNameResolver;
}

@Override
public Builder<T> withRequirementNameResolver(Function<PathAddress, String[]> requirementNameResolver) {
this.requirementNameResolver = requirementNameResolver;
return this;
}

/**
* Only reference the provided capability if value of the specified attribute complies with the specified predicate.
* @param attribute an attribute of the resource to use for conditional registration
* @param predicate conditionally determines whether to require this capability, depending on the resolve value of the specified attribute
*/
@Override
public Builder<T> when(AttributeDefinition attribute, Predicate<ModelNode> predicate) {
this.predicate = new BiPredicate<>() {
@Override
Expand All @@ -133,10 +175,7 @@ public boolean test(OperationContext context, Resource resource) {
return this;
}

/**
* Builds the configured capability reference recorder.
* @return a capability reference recorder
*/
@Override
public org.wildfly.subsystem.resource.capability.ResourceCapabilityReferenceRecorder<T> build() {
return new ResourceCapabilityServiceDescriptorReference<>(this.capability, this.requirement, this.requirementNameResolver, this.predicate);
}
Expand Down Expand Up @@ -194,23 +233,8 @@ public void removeCapabilityRequirements(OperationContext context, Resource reso
}

private String resolveRequirementName(OperationContext context) {
String[] parts = this.getRequirementNameResolver().apply(context.getCurrentAddress());
return (parts.length > 0) ? RuntimeCapability.buildDynamicCapabilityName(this.getBaseRequirementName(), parts) : this.getBaseRequirementName();
}

static BiPredicate<OperationContext, Resource> attributePredicate(AttributeDefinition attribute, Predicate<ModelNode> predicate) {
return new BiPredicate<>() {
@Override
public boolean test(OperationContext context, Resource resource) {
try {
return predicate.test(attribute.resolveModelAttribute(context, resource.getModel()));
} catch (OperationFailedException e) {
// OFE would be due to an expression that can't be resolved right now (OperationContext.Stage.MODEL).
// Very unlikely an expression is used and that it uses a resolution source not available in MODEL.
return true;
}
}
};
String[] segments = this.getRequirementNameResolver().apply(context.getCurrentAddress());
return (segments.length > 0) ? RuntimeCapability.buildDynamicCapabilityName(this.getBaseRequirementName(), segments) : this.getBaseRequirementName();
}
}
}
Loading

0 comments on commit 1157824

Please sign in to comment.