Skip to content

Commit 40d9839

Browse files
committed
[WFCORE-7087] Support resolution of extension expressions during preparation of a domain server launch command
1 parent 55e18a0 commit 40d9839

File tree

18 files changed

+534
-126
lines changed

18 files changed

+534
-126
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright The WildFly Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.jboss.as.controller;
7+
8+
import static org.wildfly.common.Assert.checkNotNullParam;
9+
10+
import java.util.Optional;
11+
12+
import org.jboss.as.controller.capability.CapabilityServiceSupport;
13+
import org.jboss.as.controller.capability.RuntimeCapability;
14+
import org.jboss.as.controller.capability.registry.CapabilityScope;
15+
import org.jboss.as.controller.capability.registry.ImmutableCapabilityRegistry;
16+
import org.jboss.as.controller.logging.ControllerLogger;
17+
import org.jboss.msc.service.ServiceName;
18+
19+
/**
20+
* Default implementation of {@link CapabilityServiceSupport}.
21+
*/
22+
public final class DefaultCapabilityServiceSupport implements CapabilityServiceSupport {
23+
private final ImmutableCapabilityRegistry registry;
24+
25+
/**
26+
* Creates a new DefaultCapabilityServiceSupport.
27+
* @param registry a capability registry. Cannot be {@code null}.
28+
*/
29+
public DefaultCapabilityServiceSupport(ImmutableCapabilityRegistry registry) {
30+
checkNotNullParam("registry", registry);
31+
this.registry = registry;
32+
}
33+
34+
@Override
35+
public boolean hasCapability(String capabilityName) {
36+
return registry.hasCapability(capabilityName, CapabilityScope.GLOBAL);
37+
}
38+
39+
@Override
40+
public <T> T getCapabilityRuntimeAPI(String capabilityName, Class<T> apiType) throws NoSuchCapabilityException {
41+
try {
42+
return registry.getCapabilityRuntimeAPI(capabilityName, CapabilityScope.GLOBAL, apiType);
43+
} catch (IllegalStateException e) {
44+
throw new NoSuchCapabilityException(capabilityName);
45+
}
46+
}
47+
48+
@Override
49+
public <T> T getCapabilityRuntimeAPI(String capabilityBaseName, String dynamicPart, Class<T> apiType) throws NoSuchCapabilityException {
50+
String fullName = RuntimeCapability.buildDynamicCapabilityName(capabilityBaseName, dynamicPart);
51+
return getCapabilityRuntimeAPI(fullName, apiType);
52+
}
53+
54+
@Override
55+
public <T> Optional<T> getOptionalCapabilityRuntimeAPI(String capabilityName, Class<T> apiType) {
56+
try {
57+
return Optional.of(getCapabilityRuntimeAPI(capabilityName, apiType));
58+
} catch (NoSuchCapabilityException e) {
59+
return Optional.empty();
60+
}
61+
}
62+
63+
@Override
64+
public <T> Optional<T> getOptionalCapabilityRuntimeAPI(String capabilityBaseName, String dynamicPart, Class<T> apiType) {
65+
try {
66+
return Optional.of(getCapabilityRuntimeAPI(capabilityBaseName, dynamicPart, apiType));
67+
} catch (NoSuchCapabilityException e) {
68+
return Optional.empty();
69+
}
70+
}
71+
72+
@Override
73+
public ServiceName getCapabilityServiceName(String capabilityName) {
74+
try {
75+
return registry.getCapabilityServiceName(capabilityName, CapabilityScope.GLOBAL, null);
76+
} catch (IllegalStateException | IllegalArgumentException ignore) {
77+
// ignore
78+
}
79+
ControllerLogger.ROOT_LOGGER.debugf("CapabilityServiceSupport: Parsing ServiceName for %s", capabilityName);
80+
return ServiceNameFactory.parseServiceName(capabilityName);
81+
}
82+
83+
@Override
84+
public ServiceName getCapabilityServiceName(String capabilityBaseName, String... dynamicPart) {
85+
ServiceName name = getCapabilityServiceName(capabilityBaseName);
86+
return (dynamicPart.length > 0) ? name.append(dynamicPart) : name;
87+
}
88+
}

controller/src/main/java/org/jboss/as/controller/ExpressionResolver.java

+42-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import java.util.regex.Pattern;
88

9+
import org.jboss.as.controller.capability.CapabilityServiceSupport;
910
import org.jboss.as.controller.extension.ExpressionResolverExtension;
1011
import org.jboss.as.controller.extension.ResolverExtensionRegistry;
1112
import org.jboss.as.controller.logging.ControllerLogger;
@@ -23,9 +24,9 @@ public interface ExpressionResolver {
2324
Pattern EXPRESSION_PATTERN = Pattern.compile(".*\\$\\{.*}.*");
2425

2526
/**
26-
* Resolves any expressions in the passed in ModelNode.
27-
*
28-
* Expressions may represent system properties, vaulted date, or a custom format to be handled by an
27+
* Resolves any expressions in the passed-in ModelNode.
28+
* <p/>
29+
* Expressions may represent system properties, environment variables or a custom format to be handled by an
2930
* {@link ExpressionResolverExtension} registered using the {@link ResolverExtensionRegistry}.
3031
*
3132
* @param node the ModelNode containing expressions.
@@ -47,13 +48,11 @@ public interface ExpressionResolver {
4748
ModelNode resolveExpressions(ModelNode node) throws OperationFailedException;
4849

4950
/**
50-
* Resolves any expressions in the passed in ModelNode.
51-
*
52-
* Expressions may represent system properties, vaulted date, or a custom format to be handled by an
51+
* Resolves any expressions in the passed-in ModelNode.
52+
* <p/>
53+
* Expressions may represent system properties, environment variables or a custom format to be handled by an
5354
* {@link ExpressionResolverExtension} registered using the {@link ResolverExtensionRegistry}.
5455
*
55-
* For vaulted data the format is ${VAULT::vault_block::attribute_name::sharedKey}
56-
*
5756
* @param node the ModelNode containing expressions.
5857
* @param context the current {@code OperationContext} to provide additional contextual information.
5958
* @return a copy of the node with expressions resolved
@@ -75,6 +74,41 @@ default ModelNode resolveExpressions(ModelNode node, OperationContext context) t
7574
return resolveExpressions(node);
7675
}
7776

77+
/**
78+
* Resolves any expressions in the passed-in ModelNode.
79+
* <p/>
80+
* Expressions may represent system properties, environment variables or a custom format to be handled by an
81+
* {@link ExpressionResolverExtension} registered using the {@link ResolverExtensionRegistry}.
82+
*
83+
* @param node the ModelNode containing expressions.
84+
* @param capabilitySupport support object for accessing capability-backed APIs.
85+
* @return a copy of the node with expressions resolved
86+
*
87+
* @throws ExpressionResolutionUserException if {@code expression} is a form understood by the resolver but in some
88+
* way is unacceptable. This should only be thrown due to flaws in the
89+
* provided {@code expression} or the configuration of resources used by
90+
* the resolver extension, which are 'user' problems>. It should not
91+
* be used for internal problems in the resolver extension. If a
92+
* if a security manager exists and its
93+
* {@link SecurityManager#checkPermission checkPermission} method doesn't
94+
* allow access to a relevant system property or environment variable,
95+
* an {@code ExpressionResolutionUserException} should be thrown
96+
* @throws ExpressionResolver.ExpressionResolutionServerException if some other internal expression resolution failure occurs.
97+
*/
98+
default ModelNode resolveExpressions(ModelNode node, CapabilityServiceSupport capabilitySupport) {
99+
try {
100+
return resolveExpressions(node);
101+
} catch (OperationFailedException e) {
102+
// This can be thrown because supposedly an ExpressionResolverExtension could throw
103+
// it from ExpressionResolverExtension.initialize(OperationContext). But per the initialize()
104+
// javadoc it should only do that in response to a user problem determined by using the OperationContext.
105+
// But there is no OperationContext passed in a call to resolveExpressions(ModelNode)!
106+
// That method should remove 'throws OperationFailedException', but that would be a breaking API change.
107+
// So this shouldn't happen and if it does something has gone wrong
108+
throw new IllegalStateException(e);
109+
}
110+
}
111+
78112
/**
79113
* An {@code ExpressionResolver} that can only resolve from system properties
80114
* and environment variables. Should not be used for most product resolution use cases as it does

0 commit comments

Comments
 (0)