Skip to content

Commit

Permalink
WFCORE-6663 Add new AttributeDefinition implementations that resolves…
Browse files Browse the repository at this point in the history
… a model directly to a ServiceDependency.
  • Loading branch information
pferraro committed Aug 20, 2024
1 parent 1a2d0ba commit 07f1885
Show file tree
Hide file tree
Showing 16 changed files with 1,133 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
public class PrimitiveListAttributeDefinition extends ListAttributeDefinition {
private final ModelType valueType;

PrimitiveListAttributeDefinition(final ListAttributeDefinition.Builder builder, ModelType valueType) {
protected PrimitiveListAttributeDefinition(final ListAttributeDefinition.Builder builder, ModelType valueType) {
super(builder);
this.valueType = valueType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
/**
* @author <a href="mailto:[email protected]">Tomaz Cerar</a>
*/
public final class StringListAttributeDefinition extends PrimitiveListAttributeDefinition {
public class StringListAttributeDefinition extends PrimitiveListAttributeDefinition {

private StringListAttributeDefinition(Builder builder) {
protected StringListAttributeDefinition(Builder builder) {
super(builder, ModelType.STRING);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@

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

/**
* Resolves a value from a resource model.
*/
public interface ResourceModelResolver<T> {
public interface ResourceModelResolver<T> extends ResourceResolver<T> {

@Override
default T resolve(OperationContext context, Resource resource) throws OperationFailedException {
return this.resolve(context, resource.getModel());
}

/**
* Resolves a value from the specified resource model, using the specified operation context.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/

package org.wildfly.subsystem.resource;

import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.registry.Resource;

/**
* Resolves a value from a resource.
*/
public interface ResourceResolver<T> {

/**
* Resolves a value from the specified resource, using the specified operation context.
* @param context an operation context
* @param resource a resource
* @return the resolved value
* @throws OperationFailedException if the value could not be resolved
*/
default T resolve(OperationContext context) throws OperationFailedException {
return this.resolve(context, context.readResource(PathAddress.EMPTY_ADDRESS, false));
}

/**
* Resolves a value from the specified resource, using the specified operation context.
* @param context an operation context
* @param resource a resource
* @return the resolved value
* @throws OperationFailedException if the value could not be resolved
*/
T resolve(OperationContext context, Resource resource) throws OperationFailedException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/

package org.wildfly.subsystem.resource;

import java.util.Set;

import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.registry.Resource;
import org.jboss.dmr.ModelNode;

/**
* A resource facade for an existing resource model, i.e. with no children
*/
public class SimpleResource implements Resource {
private final ModelNode model;

public SimpleResource(ModelNode model) {
this.model = model;
}

@Override
public ModelNode getModel() {
return this.model;
}

@Override
public void writeModel(ModelNode newModel) {
throw new UnsupportedOperationException();
}

@Override
public boolean isModelDefined() {
return this.model.isDefined();
}

@Override
public boolean hasChild(PathElement element) {
return false;
}

@Override
public Resource getChild(PathElement element) {
return null;
}

@Override
public Resource requireChild(PathElement element) {
throw new NoSuchResourceException(element);
}

@Override
public boolean hasChildren(String childType) {
return false;
}

@Override
public Resource navigate(PathAddress address) {
if (address.size() == 0) return this;
throw new NoSuchResourceException(address.getElement(0));
}

@Override
public Set<String> getChildTypes() {
return Set.of();
}

@Override
public Set<String> getChildrenNames(String childType) {
return Set.of();
}

@Override
public Set<ResourceEntry> getChildren(String childType) {
return Set.of();
}

@Override
public void registerChild(PathElement address, Resource resource) {
throw new UnsupportedOperationException();
}

@Override
public void registerChild(PathElement address, int index, Resource resource) {
throw new UnsupportedOperationException();
}

@Override
public Resource removeChild(PathElement address) {
throw new UnsupportedOperationException();
}

@Override
public Set<String> getOrderedChildTypes() {
return Set.of();
}

@Override
public boolean isRuntime() {
return false;
}

@Override
public boolean isProxy() {
return false;
}

@Override
public Resource clone() {
return new SimpleResource(this.model.clone());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.function.Function;
import java.util.function.UnaryOperator;

Expand Down Expand Up @@ -53,7 +54,7 @@ default String getBaseDependentName() {
* @param requirement the requirement of the specified capability
*/
static <T> Builder<T> builder(RuntimeCapability<Void> capability, UnaryServiceDescriptor<T> requirement) {
return new DefaultBuilder<>(capability, requirement);
return new DefaultBuilder<>(capability, NaryServiceDescriptor.of(requirement));
}

/**
Expand All @@ -63,7 +64,7 @@ static <T> Builder<T> builder(RuntimeCapability<Void> capability, UnaryServiceDe
* @param requirement the requirement of the specified capability
*/
static <T> ParentPathProvider<T> builder(RuntimeCapability<Void> capability, BinaryServiceDescriptor<T> requirement) {
return new DefaultBuilder<>(capability, requirement);
return new DefaultBuilder<>(capability, NaryServiceDescriptor.of(requirement));
}

/**
Expand All @@ -73,7 +74,7 @@ static <T> ParentPathProvider<T> builder(RuntimeCapability<Void> capability, Bin
* @param requirement the requirement of the specified capability
*/
static <T> GrandparentPathProvider<T> builder(RuntimeCapability<Void> capability, TernaryServiceDescriptor<T> requirement) {
return new DefaultBuilder<>(capability, requirement);
return new DefaultBuilder<>(capability, NaryServiceDescriptor.of(requirement));
}

/**
Expand All @@ -83,7 +84,7 @@ static <T> GrandparentPathProvider<T> builder(RuntimeCapability<Void> capability
* @param requirement the requirement of the specified capability
*/
static <T> GreatGrandparentPathProvider<T> builder(RuntimeCapability<Void> capability, QuaternaryServiceDescriptor<T> requirement) {
return new DefaultBuilder<>(capability, requirement);
return new DefaultBuilder<>(capability, NaryServiceDescriptor.of(requirement));
}

interface Builder<T> {
Expand Down Expand Up @@ -188,11 +189,11 @@ class DefaultBuilder<T> implements GreatGrandparentPathProvider<T>, GrandparentP
private static final UnaryOperator<String> CHILD_REQUIREMENT_PATTERN_SEGMENT_RESOLVER = UnaryOperator.identity();

private final RuntimeCapability<Void> capability;
private final ServiceDescriptor<T> requirement;
private final NaryServiceDescriptor<T> requirement;
private final List<RequirementNameSegmentResolver> requirementNameSegmentResolvers = new ArrayList<>(4);
private final List<UnaryOperator<String>> requirementPatternSegmentResolvers= new ArrayList<>(4);

DefaultBuilder(RuntimeCapability<Void> capability, ServiceDescriptor<T> requirement) {
DefaultBuilder(RuntimeCapability<Void> capability, NaryServiceDescriptor<T> requirement) {
this.capability = capability;
this.requirement = requirement;
}
Expand Down Expand Up @@ -244,7 +245,7 @@ private static RequirementNameSegmentResolver createRequirementNameSegmentResolv
@Override
public String resolve(OperationContext context, Resource resource, String value) {
try {
return attribute.resolveModelAttribute(context, resource.getModel()).asString();
return attribute.resolveModelAttribute(context, resource.getModel()).asStringOrNull();
} catch (OperationFailedException e) {
throw new IllegalArgumentException(e);
}
Expand Down Expand Up @@ -290,9 +291,9 @@ public CapabilityReference<T> build() {
abstract class AbstractServiceDescriptorReference<T> implements CapabilityReference<T> {

private final RuntimeCapability<Void> capability;
private final ServiceDescriptor<T> requirement;
private final NaryServiceDescriptor<T> requirement;

AbstractServiceDescriptorReference(RuntimeCapability<Void> capability, ServiceDescriptor<T> requirement) {
AbstractServiceDescriptorReference(RuntimeCapability<Void> capability, NaryServiceDescriptor<T> requirement) {
this.capability = capability;
this.requirement = requirement;
}
Expand All @@ -303,7 +304,7 @@ public RuntimeCapability<Void> getDependent() {
}

@Override
public ServiceDescriptor<T> getRequirement() {
public NaryServiceDescriptor<T> getRequirement() {
return this.requirement;
}

Expand All @@ -327,20 +328,20 @@ class ServiceDescriptorReference<T> extends AbstractServiceDescriptorReference<T
private final List<RequirementNameSegmentResolver> requirementNameSegmentResolvers;
private final List<UnaryOperator<String>> requirementPatternSegmentResolvers;

ServiceDescriptorReference(RuntimeCapability<Void> capability, ServiceDescriptor<T> requirement, List<RequirementNameSegmentResolver> requirementNameSegmentResolvers, List<UnaryOperator<String>> requirementPatternSegmentResolvers) {
ServiceDescriptorReference(RuntimeCapability<Void> capability, NaryServiceDescriptor<T> requirement, List<RequirementNameSegmentResolver> requirementNameSegmentResolvers, List<UnaryOperator<String>> requirementPatternSegmentResolvers) {
super(capability, requirement);
this.requirementNameSegmentResolvers = List.copyOf(requirementNameSegmentResolvers);
this.requirementPatternSegmentResolvers = List.copyOf(requirementPatternSegmentResolvers);
}

@Override
public String[] resolve(OperationContext context, Resource resource, String value) {
public Map.Entry<String, String[]> resolve(OperationContext context, Resource resource, String value) {
String[] segments = new String[this.requirementNameSegmentResolvers.size()];
ListIterator<RequirementNameSegmentResolver> resolvers = this.requirementNameSegmentResolvers.listIterator();
while (resolvers.hasNext()) {
segments[resolvers.nextIndex()] = resolvers.next().resolve(context, resource, value);
}
return segments;
return this.getRequirement().resolve(segments);
}

@Override
Expand All @@ -366,7 +367,8 @@ public void removeCapabilityRequirements(OperationContext context, Resource reso
}

private String resolveRequirementName(OperationContext context, Resource resource, String value) {
return RuntimeCapability.buildDynamicCapabilityName(this.getBaseRequirementName(), this.resolve(context, resource, value));
Map.Entry<String, String[]> resolved = this.resolve(context, resource, value);
return (resolved.getValue().length > 0) ? RuntimeCapability.buildDynamicCapabilityName(resolved.getKey(), resolved.getValue()) : resolved.getKey();
}

@Override
Expand Down
Loading

0 comments on commit 07f1885

Please sign in to comment.