Polish endpoint

This commit is contained in:
Phillip Webb
2017-08-28 18:17:29 -07:00
committed by Stephane Nicoll
parent 98455e30dc
commit f9e5b07eec
42 changed files with 634 additions and 648 deletions

View File

@@ -23,7 +23,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.endpoint.Endpoint;
import org.springframework.boot.endpoint.EndpointType;
import org.springframework.boot.endpoint.EndpointDelivery;
import org.springframework.context.annotation.Conditional;
/**
@@ -33,8 +33,8 @@ import org.springframework.context.annotation.Conditional;
* <p>
* If no specific {@code endpoints.<id>.*} or {@code endpoints.default.*} properties are
* defined, the condition matches the {@code enabledByDefault} value regardless of the
* specific {@link EndpointType}, if any. If any property are set, they are evaluated with
* a sensible order of precedence.
* specific {@link EndpointDelivery}, if any. If any property are set, they are evaluated
* with a sensible order of precedence.
* <p>
* For instance if {@code endpoints.default.enabled} is {@code false} but
* {@code endpoints.<id>.enabled} is {@code true}, the condition will match.

View File

@@ -22,7 +22,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionMessage;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.endpoint.Endpoint;
import org.springframework.boot.endpoint.EndpointType;
import org.springframework.boot.endpoint.EndpointDelivery;
import org.springframework.boot.endpoint.jmx.JmxEndpointExtension;
import org.springframework.boot.endpoint.web.WebEndpointExtension;
import org.springframework.context.annotation.Bean;
@@ -30,6 +30,7 @@ import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.core.type.MethodMetadata;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -44,14 +45,9 @@ class OnEnabledEndpointCondition extends SpringBootCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
EndpointAttributes endpoint = getEndpointAttributes(context, metadata);
if (!StringUtils.hasText(endpoint.id)) {
throw new IllegalStateException("Endpoint id could not be determined");
}
EndpointEnablementProvider enablementProvider = new EndpointEnablementProvider(
context.getEnvironment());
EndpointEnablement endpointEnablement = enablementProvider.getEndpointEnablement(
endpoint.id, endpoint.enabled, endpoint.endpointType);
EndpointAttributes attributes = getEndpointAttributes(context, metadata);
EndpointEnablement endpointEnablement = attributes
.getEnablement(new EndpointEnablementProvider(context.getEnvironment()));
return new ConditionOutcome(endpointEnablement.isEnabled(),
ConditionMessage.forCondition(ConditionalOnEnabledEndpoint.class)
.because(endpointEnablement.getReason()));
@@ -59,24 +55,27 @@ class OnEnabledEndpointCondition extends SpringBootCondition {
private EndpointAttributes getEndpointAttributes(ConditionContext context,
AnnotatedTypeMetadata metadata) {
if (metadata instanceof MethodMetadata
&& metadata.isAnnotated(Bean.class.getName())) {
MethodMetadata methodMetadata = (MethodMetadata) metadata;
try {
// We should be safe to load at this point since we are in the
// REGISTER_BEAN phase
Class<?> returnType = ClassUtils.forName(
methodMetadata.getReturnTypeName(), context.getClassLoader());
return extractEndpointAttributes(returnType);
}
catch (Throwable ex) {
throw new IllegalStateException("Failed to extract endpoint id for "
+ methodMetadata.getDeclaringClassName() + "."
+ methodMetadata.getMethodName(), ex);
}
}
throw new IllegalStateException(
Assert.state(
metadata instanceof MethodMetadata
&& metadata.isAnnotated(Bean.class.getName()),
"OnEnabledEndpointCondition may only be used on @Bean methods");
return getEndpointAttributes(context, (MethodMetadata) metadata);
}
private EndpointAttributes getEndpointAttributes(ConditionContext context,
MethodMetadata methodMetadata) {
try {
// We should be safe to load at this point since we are in the
// REGISTER_BEAN phase
Class<?> returnType = ClassUtils.forName(methodMetadata.getReturnTypeName(),
context.getClassLoader());
return extractEndpointAttributes(returnType);
}
catch (Throwable ex) {
throw new IllegalStateException("Failed to extract endpoint id for "
+ methodMetadata.getDeclaringClassName() + "."
+ methodMetadata.getMethodName(), ex);
}
}
protected EndpointAttributes extractEndpointAttributes(Class<?> type) {
@@ -105,11 +104,10 @@ class OnEnabledEndpointCondition extends SpringBootCondition {
if (endpoint == null) {
return null;
}
// If both types are set, all techs are exposed
EndpointType endpointType = (endpoint.types().length == 1 ? endpoint.types()[0]
: null);
// If both types are set, all delivery technologies are exposed
EndpointDelivery[] delivery = endpoint.delivery();
return new EndpointAttributes(endpoint.id(), endpoint.enabledByDefault(),
endpointType);
(delivery.length == 1 ? delivery[0] : null));
}
private static class EndpointAttributes {
@@ -118,12 +116,19 @@ class OnEnabledEndpointCondition extends SpringBootCondition {
private final boolean enabled;
private final EndpointType endpointType;
private final EndpointDelivery delivery;
EndpointAttributes(String id, boolean enabled, EndpointType endpointType) {
EndpointAttributes(String id, boolean enabled, EndpointDelivery delivery) {
if (!StringUtils.hasText(id)) {
throw new IllegalStateException("Endpoint id could not be determined");
}
this.id = id;
this.enabled = enabled;
this.endpointType = endpointType;
this.delivery = delivery;
}
public EndpointEnablement getEnablement(EndpointEnablementProvider provider) {
return provider.getEndpointEnablement(this.id, this.enabled, this.delivery);
}
}

View File

@@ -34,7 +34,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.endpoint.ConversionServiceOperationParameterMapper;
import org.springframework.boot.endpoint.EndpointType;
import org.springframework.boot.endpoint.EndpointDelivery;
import org.springframework.boot.endpoint.OperationParameterMapper;
import org.springframework.boot.endpoint.jmx.EndpointMBeanRegistrar;
import org.springframework.boot.endpoint.jmx.JmxAnnotationEndpointDiscoverer;
@@ -102,10 +102,10 @@ public class EndpointInfrastructureAutoConfiguration {
ObjectProvider<ObjectMapper> objectMapper) {
EndpointProvider<JmxEndpointOperation> endpointProvider = new EndpointProvider<>(
this.applicationContext.getEnvironment(), endpointDiscoverer,
EndpointType.JMX);
EndpointDelivery.JMX);
EndpointMBeanRegistrar endpointMBeanRegistrar = new EndpointMBeanRegistrar(
mBeanServer, new DefaultEndpointObjectNameFactory(properties,
mBeanServer, ObjectUtils.getIdentityHexString(this.applicationContext)));
mBeanServer, new DefaultEndpointObjectNameFactory(properties, mBeanServer,
ObjectUtils.getIdentityHexString(this.applicationContext)));
return new JmxEndpointExporter(endpointProvider, endpointMBeanRegistrar,
objectMapper.getIfAvailable(ObjectMapper::new));
}
@@ -127,7 +127,7 @@ public class EndpointInfrastructureAutoConfiguration {
return new EndpointProvider<>(this.applicationContext.getEnvironment(),
webEndpointDiscoverer(operationParameterMapper,
cachingConfigurationFactory),
EndpointType.WEB);
EndpointDelivery.WEB);
}
private WebAnnotationEndpointDiscoverer webEndpointDiscoverer(

View File

@@ -20,10 +20,10 @@ import java.util.Collection;
import java.util.stream.Collectors;
import org.springframework.boot.actuate.autoconfigure.endpoint.support.EndpointEnablementProvider;
import org.springframework.boot.endpoint.EndpointDelivery;
import org.springframework.boot.endpoint.EndpointDiscoverer;
import org.springframework.boot.endpoint.EndpointInfo;
import org.springframework.boot.endpoint.EndpointOperation;
import org.springframework.boot.endpoint.EndpointType;
import org.springframework.boot.endpoint.Operation;
import org.springframework.core.env.Environment;
/**
@@ -34,25 +34,25 @@ import org.springframework.core.env.Environment;
* @author Stephane Nicoll
* @since 2.0.0
*/
public final class EndpointProvider<T extends EndpointOperation> {
public final class EndpointProvider<T extends Operation> {
private final EndpointDiscoverer<T> discoverer;
private final EndpointEnablementProvider endpointEnablementProvider;
private final EndpointType endpointType;
private final EndpointDelivery delivery;
/**
* Creates a new instance.
* @param environment the environment to use to check the endpoints that are enabled
* @param discoverer the discoverer to get the initial set of endpoints
* @param endpointType the type of endpoint to handle
* @param delivery the delivery technology for the endpoint
*/
public EndpointProvider(Environment environment, EndpointDiscoverer<T> discoverer,
EndpointType endpointType) {
EndpointDelivery delivery) {
this.discoverer = discoverer;
this.endpointEnablementProvider = new EndpointEnablementProvider(environment);
this.endpointType = endpointType;
this.delivery = delivery;
}
public Collection<EndpointInfo<T>> getEndpoints() {
@@ -62,7 +62,7 @@ public final class EndpointProvider<T extends EndpointOperation> {
private boolean isEnabled(EndpointInfo<?> endpoint) {
return this.endpointEnablementProvider.getEndpointEnablement(endpoint.getId(),
endpoint.isEnabledByDefault(), this.endpointType).isEnabled();
endpoint.isEnabledByDefault(), this.delivery).isEnabled();
}
}

View File

@@ -25,6 +25,7 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.support;
public final class EndpointEnablement {
private final boolean enabled;
private final String reason;
/**

View File

@@ -16,9 +16,9 @@
package org.springframework.boot.actuate.autoconfigure.endpoint.support;
import org.springframework.boot.endpoint.EndpointType;
import org.springframework.boot.endpoint.EndpointDelivery;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
import org.springframework.util.Assert;
/**
* Determines an endpoint's enablement based on the current {@link Environment}.
@@ -54,109 +54,111 @@ public class EndpointEnablementProvider {
* Return the {@link EndpointEnablement} of an endpoint for a specific tech exposure.
* @param endpointId the id of the endpoint
* @param enabledByDefault whether the endpoint is enabled by default or not
* @param endpointType the requested {@link EndpointType}
* @param delivery the requested {@link EndpointDelivery}
* @return the {@link EndpointEnablement} of that endpoint for the specified
* {@link EndpointType}
* {@link EndpointDelivery}
*/
public EndpointEnablement getEndpointEnablement(String endpointId,
boolean enabledByDefault, EndpointType endpointType) {
if (!StringUtils.hasText(endpointId)) {
throw new IllegalArgumentException("Endpoint id must have a value");
boolean enabledByDefault, EndpointDelivery delivery) {
Assert.hasText(endpointId, "Endpoint id must have a value");
Assert.isTrue(!endpointId.equals("default"), "Endpoint id 'default' is a reserved "
+ "value and cannot be used by an endpoint");
EndpointEnablement result = findEnablement(endpointId, delivery);
if (result != null) {
return result;
}
if (endpointId.equals("default")) {
throw new IllegalArgumentException("Endpoint id 'default' is a reserved "
+ "value and cannot be used by an endpoint");
result = findEnablement(getKey(endpointId, "enabled"));
if (result != null) {
return result;
}
if (endpointType != null) {
String endpointTypeKey = createTechSpecificKey(endpointId, endpointType);
EndpointEnablement endpointTypeSpecificOutcome = getEnablementFor(
endpointTypeKey);
if (endpointTypeSpecificOutcome != null) {
return endpointTypeSpecificOutcome;
}
}
else {
// If any tech specific is on at this point we should enable the endpoint
EndpointEnablement anyTechSpecificOutcome = getAnyTechSpecificOutcomeFor(
endpointId);
if (anyTechSpecificOutcome != null) {
return anyTechSpecificOutcome;
}
}
String endpointKey = createKey(endpointId, "enabled");
EndpointEnablement endpointSpecificOutcome = getEnablementFor(endpointKey);
if (endpointSpecificOutcome != null) {
return endpointSpecificOutcome;
}
// All endpoints specific attributes have been looked at. Checking default value
// for the endpoint
if (!enabledByDefault) {
return defaultEndpointEnablement(endpointId, false, endpointType);
return getDefaultEndpointEnablement(endpointId, false, delivery);
}
if (endpointType != null) {
String defaultTypeKey = createTechSpecificKey("default", endpointType);
EndpointEnablement globalTypeOutcome = getEnablementFor(defaultTypeKey);
if (globalTypeOutcome != null) {
return globalTypeOutcome;
}
if (!endpointType.isEnabledByDefault()) {
return defaultEndpointEnablement("default", false, endpointType);
}
}
else {
// Check if there is a global tech required
EndpointEnablement anyTechGeneralOutcome = getAnyTechSpecificOutcomeFor(
"default");
if (anyTechGeneralOutcome != null) {
return anyTechGeneralOutcome;
}
}
String defaultKey = createKey("default", "enabled");
EndpointEnablement globalOutCome = getEnablementFor(defaultKey);
if (globalOutCome != null) {
return globalOutCome;
}
return defaultEndpointEnablement(endpointId, enabledByDefault, endpointType);
return getGlobalEndpointEnablement(endpointId, enabledByDefault,
delivery);
}
private EndpointEnablement defaultEndpointEnablement(String endpointId,
boolean enabledByDefault, EndpointType endpointType) {
return new EndpointEnablement(enabledByDefault, createDefaultEnablementMessage(
endpointId, enabledByDefault, endpointType));
}
private String createDefaultEnablementMessage(String endpointId,
boolean enabledByDefault, EndpointType endpointType) {
StringBuilder sb = new StringBuilder();
sb.append(String.format("endpoint '%s' ", endpointId));
if (endpointType != null) {
sb.append(String.format("(%s) ", endpointType.name().toLowerCase()));
private EndpointEnablement findEnablement(String endpointId,
EndpointDelivery delivery) {
if (delivery != null) {
return findEnablement(getKey(endpointId, delivery));
}
sb.append(String.format("is %s by default",
(enabledByDefault ? "enabled" : "disabled")));
return sb.toString();
return findEnablementForAnyDeliveryTechnology(endpointId);
}
private EndpointEnablement getAnyTechSpecificOutcomeFor(String endpointId) {
for (EndpointType endpointType : EndpointType.values()) {
String key = createTechSpecificKey(endpointId, endpointType);
EndpointEnablement outcome = getEnablementFor(key);
if (outcome != null && outcome.isEnabled()) {
return outcome;
private EndpointEnablement getGlobalEndpointEnablement(String endpointId,
boolean enabledByDefault, EndpointDelivery delivery) {
EndpointEnablement result = findGlobalEndpointEnablement(delivery);
if (result != null) {
return result;
}
result = findEnablement(getKey("default", "enabled"));
if (result != null) {
return result;
}
return getDefaultEndpointEnablement(endpointId, enabledByDefault,
delivery);
}
private EndpointEnablement findGlobalEndpointEnablement(
EndpointDelivery delivery) {
if (delivery != null) {
EndpointEnablement result = findEnablement(getKey("default", delivery));
if (result != null) {
return result;
}
if (!delivery.isEnabledByDefault()) {
return getDefaultEndpointEnablement("default", false, delivery);
}
return null;
}
return findEnablementForAnyDeliveryTechnology("default");
}
private EndpointEnablement findEnablementForAnyDeliveryTechnology(String endpointId) {
for (EndpointDelivery candidate : EndpointDelivery.values()) {
EndpointEnablement result = findEnablementForDeliveryTechnology(endpointId,
candidate);
if (result != null && result.isEnabled()) {
return result;
}
}
return null;
}
private String createTechSpecificKey(String endpointId, EndpointType endpointType) {
return createKey(endpointId, endpointType.name().toLowerCase() + ".enabled");
private EndpointEnablement findEnablementForDeliveryTechnology(String endpointId,
EndpointDelivery delivery) {
String endpointTypeKey = getKey(endpointId, delivery);
EndpointEnablement endpointTypeSpecificOutcome = findEnablement(endpointTypeKey);
return endpointTypeSpecificOutcome;
}
private String createKey(String endpointId, String suffix) {
private EndpointEnablement getDefaultEndpointEnablement(String endpointId,
boolean enabledByDefault, EndpointDelivery delivery) {
return new EndpointEnablement(enabledByDefault, createDefaultEnablementMessage(
endpointId, enabledByDefault, delivery));
}
private String createDefaultEnablementMessage(String endpointId,
boolean enabledByDefault, EndpointDelivery delivery) {
StringBuilder message = new StringBuilder();
message.append(String.format("endpoint '%s' ", endpointId));
if (delivery != null) {
message.append(
String.format("(%s) ", delivery.name().toLowerCase()));
}
message.append(String.format("is %s by default",
(enabledByDefault ? "enabled" : "disabled")));
return message.toString();
}
private String getKey(String endpointId, EndpointDelivery delivery) {
return getKey(endpointId, delivery.name().toLowerCase() + ".enabled");
}
private String getKey(String endpointId, String suffix) {
return "endpoints." + endpointId + "." + suffix;
}
@@ -166,7 +168,7 @@ public class EndpointEnablementProvider {
* @param key the key to check
* @return the outcome or {@code null} if the key is no set
*/
private EndpointEnablement getEnablementFor(String key) {
private EndpointEnablement findEnablement(String key) {
if (this.environment.containsProperty(key)) {
boolean match = this.environment.getProperty(key, Boolean.class, true);
return new EndpointEnablement(match, String.format("found property %s", key));

View File

@@ -111,7 +111,7 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebEndpointSe
@Override
protected void registerMappingForOperation(WebEndpointOperation operation) {
registerMapping(createRequestMappingInfo(operation),
new OperationHandler(operation.getOperationInvoker(), operation.getId(), this.securityInterceptor), this.handle);
new OperationHandler(operation.getInvoker(), operation.getId(), this.securityInterceptor), this.handle);
}
/**

View File

@@ -36,7 +36,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.endpoint.Endpoint;
import org.springframework.boot.endpoint.EndpointType;
import org.springframework.boot.endpoint.EndpointDelivery;
import org.springframework.boot.endpoint.ReadOperation;
import org.springframework.boot.endpoint.web.WebEndpointResponse;
import org.springframework.core.io.FileSystemResource;
@@ -55,7 +55,7 @@ import org.springframework.util.ReflectionUtils;
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "endpoints.heapdump")
@Endpoint(id = "heapdump", types = EndpointType.WEB)
@Endpoint(id = "heapdump", delivery = EndpointDelivery.WEB)
public class HeapDumpWebEndpoint {
private final long timeout;

View File

@@ -23,7 +23,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.endpoint.Endpoint;
import org.springframework.boot.endpoint.EndpointType;
import org.springframework.boot.endpoint.EndpointDelivery;
import org.springframework.boot.endpoint.ReadOperation;
import org.springframework.boot.logging.LogFile;
import org.springframework.core.env.Environment;
@@ -39,7 +39,7 @@ import org.springframework.core.io.Resource;
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "endpoints.logfile")
@Endpoint(id = "logfile", types = EndpointType.WEB)
@Endpoint(id = "logfile", delivery = EndpointDelivery.WEB)
public class LogFileWebEndpoint {
private static final Log logger = LogFactory.getLog(LogFileWebEndpoint.class);

View File

@@ -19,7 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.endpoint;
import org.junit.Test;
import org.springframework.boot.endpoint.Endpoint;
import org.springframework.boot.endpoint.EndpointType;
import org.springframework.boot.endpoint.EndpointDelivery;
import org.springframework.boot.endpoint.jmx.JmxEndpointExtension;
import org.springframework.boot.endpoint.web.WebEndpointExtension;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@@ -297,8 +297,8 @@ public class ConditionalOnEnabledEndpointTests {
}
@Endpoint(id = "bar", types = { EndpointType.WEB,
EndpointType.JMX }, enabledByDefault = false)
@Endpoint(id = "bar", delivery = { EndpointDelivery.WEB,
EndpointDelivery.JMX }, enabledByDefault = false)
static class BarEndpoint {
}
@@ -314,7 +314,7 @@ public class ConditionalOnEnabledEndpointTests {
}
@Endpoint(id = "onlyweb", types = EndpointType.WEB)
@Endpoint(id = "onlyweb", delivery = EndpointDelivery.WEB)
static class OnlyWebEndpoint {
}

View File

@@ -20,7 +20,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.endpoint.EndpointType;
import org.springframework.boot.endpoint.EndpointDelivery;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.util.ObjectUtils;
@@ -41,7 +41,7 @@ public class EndpointEnablementProviderTests {
public void cannotDetermineEnablementWithEmptyEndpoint() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Endpoint id must have a value");
determineEnablement(" ", true);
getEndpointEnablement(" ", true);
}
@Test
@@ -49,289 +49,295 @@ public class EndpointEnablementProviderTests {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Endpoint id 'default' is a reserved value and cannot "
+ "be used by an endpoint");
determineEnablement("default", true);
getEndpointEnablement("default", true);
}
@Test
public void generalEnabledByDefault() {
validate(determineEnablement("foo", true), true,
"endpoint 'foo' is enabled by default");
EndpointEnablement enablement = getEndpointEnablement("foo", true);
validate(enablement, true, "endpoint 'foo' is enabled by default");
}
@Test
public void generalDisabledViaSpecificProperty() {
validate(determineEnablement("foo", true, "endpoints.foo.enabled=false"), false,
"found property endpoints.foo.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
"endpoints.foo.enabled=false");
validate(enablement, false, "found property endpoints.foo.enabled");
}
@Test
public void generalDisabledViaGeneralProperty() {
validate(determineEnablement("foo", true, "endpoints.default.enabled=false"), false,
"found property endpoints.default.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
"endpoints.default.enabled=false");
validate(enablement, false, "found property endpoints.default.enabled");
}
@Test
public void generalEnabledOverrideViaSpecificProperty() {
validate(
determineEnablement("foo", true, "endpoints.default.enabled=false",
"endpoints.foo.enabled=true"),
true, "found property endpoints.foo.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
"endpoints.default.enabled=false", "endpoints.foo.enabled=true");
validate(enablement, true, "found property endpoints.foo.enabled");
}
@Test
public void generalEnabledOverrideViaSpecificWebProperty() {
validate(
determineEnablement("foo", true, "endpoints.foo.enabled=false",
"endpoints.foo.web.enabled=true"),
true, "found property endpoints.foo.web.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
"endpoints.foo.enabled=false", "endpoints.foo.web.enabled=true");
validate(enablement, true, "found property endpoints.foo.web.enabled");
}
@Test
public void generalEnabledOverrideViaSpecificJmxProperty() {
validate(
determineEnablement("foo", true, "endpoints.foo.enabled=false",
"endpoints.foo.jmx.enabled=true"),
true, "found property endpoints.foo.jmx.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
"endpoints.foo.enabled=false", "endpoints.foo.jmx.enabled=true");
validate(enablement, true, "found property endpoints.foo.jmx.enabled");
}
@Test
public void generalEnabledOverrideViaSpecificAnyProperty() {
validate(determineEnablement("foo", true, "endpoints.foo.enabled=false",
validate(getEndpointEnablement("foo", true, "endpoints.foo.enabled=false",
"endpoints.foo.web.enabled=false", "endpoints.foo.jmx.enabled=true"),
true, "found property endpoints.foo.jmx.enabled");
}
@Test
public void generalEnabledOverrideViaGeneralWebProperty() {
validate(
determineEnablement("foo", true, "endpoints.default.enabled=false",
"endpoints.default.web.enabled=true"),
true, "found property endpoints.default.web.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
"endpoints.default.enabled=false", "endpoints.default.web.enabled=true");
validate(enablement, true, "found property endpoints.default.web.enabled");
}
@Test
public void generalEnabledOverrideViaGeneralJmxProperty() {
validate(
determineEnablement("foo", true, "endpoints.default.enabled=false",
"endpoints.default.jmx.enabled=true"),
true, "found property endpoints.default.jmx.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
"endpoints.default.enabled=false", "endpoints.default.jmx.enabled=true");
validate(enablement, true, "found property endpoints.default.jmx.enabled");
}
@Test
public void generalEnabledOverrideViaGeneralAnyProperty() {
validate(determineEnablement("foo", true, "endpoints.default.enabled=false",
"endpoints.default.web.enabled=false", "endpoints.default.jmx.enabled=true"),
true, "found property endpoints.default.jmx.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
"endpoints.default.enabled=false", "endpoints.default.web.enabled=false",
"endpoints.default.jmx.enabled=true");
validate(enablement, true, "found property endpoints.default.jmx.enabled");
}
@Test
public void generalDisabledEvenWithEnabledGeneralProperties() {
validate(
determineEnablement("foo", true, "endpoints.default.enabled=true",
"endpoints.default.web.enabled=true",
"endpoints.default.jmx.enabled=true", "endpoints.foo.enabled=false"),
false, "found property endpoints.foo.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
"endpoints.default.enabled=true", "endpoints.default.web.enabled=true",
"endpoints.default.jmx.enabled=true", "endpoints.foo.enabled=false");
validate(enablement, false, "found property endpoints.foo.enabled");
}
@Test
public void generalDisabledByDefaultWithAnnotationFlag() {
validate(determineEnablement("bar", false), false,
"endpoint 'bar' is disabled by default");
EndpointEnablement enablement = getEndpointEnablement("bar", false);
validate(enablement, false, "endpoint 'bar' is disabled by default");
}
@Test
public void generalDisabledByDefaultWithAnnotationFlagEvenWithGeneralProperty() {
validate(determineEnablement("bar", false, "endpoints.default.enabled=true"), false,
"endpoint 'bar' is disabled by default");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.default.enabled=true");
validate(enablement, false, "endpoint 'bar' is disabled by default");
}
@Test
public void generalDisabledByDefaultWithAnnotationFlagEvenWithGeneralWebProperty() {
validate(determineEnablement("bar", false, "endpoints.default.web.enabled=true"),
false, "endpoint 'bar' is disabled by default");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.default.web.enabled=true");
validate(enablement, false, "endpoint 'bar' is disabled by default");
}
@Test
public void generalDisabledByDefaultWithAnnotationFlagEvenWithGeneralJmxProperty() {
validate(determineEnablement("bar", false, "endpoints.default.jmx.enabled=true"),
false, "endpoint 'bar' is disabled by default");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.default.jmx.enabled=true");
validate(enablement, false, "endpoint 'bar' is disabled by default");
}
@Test
public void generalEnabledOverrideWithAndAnnotationFlagAndSpecificProperty() {
validate(determineEnablement("bar", false, "endpoints.bar.enabled=true"), true,
"found property endpoints.bar.enabled");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.bar.enabled=true");
validate(enablement, true, "found property endpoints.bar.enabled");
}
@Test
public void generalEnabledOverrideWithAndAnnotationFlagAndSpecificWebProperty() {
validate(determineEnablement("bar", false, "endpoints.bar.web.enabled=true"),
true, "found property endpoints.bar.web.enabled");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.bar.web.enabled=true");
validate(enablement, true, "found property endpoints.bar.web.enabled");
}
@Test
public void generalEnabledOverrideWithAndAnnotationFlagAndSpecificJmxProperty() {
validate(determineEnablement("bar", false, "endpoints.bar.jmx.enabled=true"),
true, "found property endpoints.bar.jmx.enabled");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.bar.jmx.enabled=true");
validate(enablement, true, "found property endpoints.bar.jmx.enabled");
}
@Test
public void generalEnabledOverrideWithAndAnnotationFlagAndAnyProperty() {
validate(
determineEnablement("bar", false, "endpoints.bar.web.enabled=false",
"endpoints.bar.jmx.enabled=true"),
true, "found property endpoints.bar.jmx.enabled");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.bar.web.enabled=false", "endpoints.bar.jmx.enabled=true");
validate(enablement, true, "found property endpoints.bar.jmx.enabled");
}
@Test
public void specificEnabledByDefault() {
validate(determineEnablement("foo", true, EndpointType.JMX), true,
"endpoint 'foo' (jmx) is enabled by default");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointDelivery.JMX);
validate(enablement, true, "endpoint 'foo' (jmx) is enabled by default");
}
@Test
public void specificDisabledViaEndpointProperty() {
validate(
determineEnablement("foo", true, EndpointType.WEB,
"endpoints.foo.enabled=false"),
false, "found property endpoints.foo.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointDelivery.WEB, "endpoints.foo.enabled=false");
validate(enablement, false, "found property endpoints.foo.enabled");
}
@Test
public void specificDisabledViaTechProperty() {
validate(
determineEnablement("foo", true, EndpointType.WEB,
"endpoints.foo.web.enabled=false"),
false, "found property endpoints.foo.web.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointDelivery.WEB, "endpoints.foo.web.enabled=false");
validate(enablement, false, "found property endpoints.foo.web.enabled");
}
@Test
public void specificNotDisabledViaUnrelatedTechProperty() {
validate(
determineEnablement("foo", true, EndpointType.JMX,
"endpoints.foo.web.enabled=false"),
true, "endpoint 'foo' (jmx) is enabled by default");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointDelivery.JMX, "endpoints.foo.web.enabled=false");
validate(enablement, true, "endpoint 'foo' (jmx) is enabled by default");
}
@Test
public void specificDisabledViaGeneralProperty() {
validate(
determineEnablement("foo", true, EndpointType.JMX,
"endpoints.default.enabled=false"),
false, "found property endpoints.default.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointDelivery.JMX, "endpoints.default.enabled=false");
validate(enablement, false, "found property endpoints.default.enabled");
}
@Test
public void specificEnabledOverrideViaEndpointProperty() {
validate(
determineEnablement("foo", true, EndpointType.WEB,
"endpoints.default.enabled=false", "endpoints.foo.enabled=true"),
true, "found property endpoints.foo.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointDelivery.WEB, "endpoints.default.enabled=false",
"endpoints.foo.enabled=true");
validate(enablement, true, "found property endpoints.foo.enabled");
}
@Test
public void specificEnabledOverrideViaTechProperty() {
validate(
determineEnablement("foo", true, EndpointType.WEB,
"endpoints.foo.enabled=false", "endpoints.foo.web.enabled=true"),
true, "found property endpoints.foo.web.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointDelivery.WEB, "endpoints.foo.enabled=false",
"endpoints.foo.web.enabled=true");
validate(enablement, true, "found property endpoints.foo.web.enabled");
}
@Test
public void specificEnabledOverrideHasNotEffectWithUnrelatedTechProperty() {
validate(
determineEnablement("foo", true, EndpointType.WEB,
"endpoints.foo.enabled=false", "endpoints.foo.jmx.enabled=true"),
false, "found property endpoints.foo.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointDelivery.WEB, "endpoints.foo.enabled=false",
"endpoints.foo.jmx.enabled=true");
validate(enablement, false, "found property endpoints.foo.enabled");
}
@Test
public void specificEnabledOverrideViaGeneralWebProperty() {
validate(
determineEnablement("foo", true, EndpointType.WEB,
"endpoints.default.enabled=false", "endpoints.default.web.enabled=true"),
true, "found property endpoints.default.web.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointDelivery.WEB, "endpoints.default.enabled=false",
"endpoints.default.web.enabled=true");
validate(enablement, true, "found property endpoints.default.web.enabled");
}
@Test
public void specificEnabledOverrideHasNoEffectWithUnrelatedTechProperty() {
validate(
determineEnablement("foo", true, EndpointType.JMX,
getEndpointEnablement("foo", true, EndpointDelivery.JMX,
"endpoints.default.enabled=false", "endpoints.default.web.enabled=true"),
false, "found property endpoints.default.enabled");
}
@Test
public void specificDisabledWithEndpointPropertyEvenWithEnabledGeneralProperties() {
validate(
determineEnablement("foo", true, EndpointType.WEB,
"endpoints.default.enabled=true", "endpoints.default.web.enabled=true",
"endpoints.default.jmx.enabled=true", "endpoints.foo.enabled=false"),
false, "found property endpoints.foo.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointDelivery.WEB, "endpoints.default.enabled=true",
"endpoints.default.web.enabled=true", "endpoints.default.jmx.enabled=true",
"endpoints.foo.enabled=false");
validate(enablement, false, "found property endpoints.foo.enabled");
}
@Test
public void specificDisabledWithTechPropertyEvenWithEnabledGeneralProperties() {
validate(
determineEnablement("foo", true, EndpointType.WEB,
"endpoints.default.enabled=true", "endpoints.default.web.enabled=true",
"endpoints.default.jmx.enabled=true", "endpoints.foo.enabled=true",
"endpoints.foo.web.enabled=false"),
false, "found property endpoints.foo.web.enabled");
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointDelivery.WEB, "endpoints.default.enabled=true",
"endpoints.default.web.enabled=true", "endpoints.default.jmx.enabled=true",
"endpoints.foo.enabled=true", "endpoints.foo.web.enabled=false");
validate(enablement, false, "found property endpoints.foo.web.enabled");
}
@Test
public void specificDisabledByDefaultWithAnnotationFlag() {
validate(determineEnablement("bar", false, EndpointType.WEB), false,
"endpoint 'bar' (web) is disabled by default");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointDelivery.WEB);
validate(enablement, false, "endpoint 'bar' (web) is disabled by default");
}
@Test
public void specificDisabledByDefaultWithAnnotationFlagEvenWithGeneralProperty() {
validate(
determineEnablement("bar", false, EndpointType.WEB,
"endpoints.default.enabled=true"),
false, "endpoint 'bar' (web) is disabled by default");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointDelivery.WEB, "endpoints.default.enabled=true");
validate(enablement, false, "endpoint 'bar' (web) is disabled by default");
}
@Test
public void specificDisabledByDefaultWithAnnotationFlagEvenWithGeneralWebProperty() {
validate(
determineEnablement("bar", false, EndpointType.WEB,
"endpoints.default.web.enabled=true"),
false, "endpoint 'bar' (web) is disabled by default");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointDelivery.WEB, "endpoints.default.web.enabled=true");
validate(enablement, false, "endpoint 'bar' (web) is disabled by default");
}
@Test
public void specificDisabledByDefaultWithAnnotationFlagEvenWithGeneralJmxProperty() {
validate(
determineEnablement("bar", false, EndpointType.WEB,
"endpoints.default.jmx.enabled=true"),
false, "endpoint 'bar' (web) is disabled by default");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointDelivery.WEB, "endpoints.default.jmx.enabled=true");
validate(enablement, false, "endpoint 'bar' (web) is disabled by default");
}
@Test
public void specificEnabledOverrideWithAndAnnotationFlagAndEndpointProperty() {
validate(
determineEnablement("bar", false, EndpointType.WEB,
"endpoints.bar.enabled=true"),
true, "found property endpoints.bar.enabled");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointDelivery.WEB, "endpoints.bar.enabled=true");
validate(enablement, true, "found property endpoints.bar.enabled");
}
@Test
public void specificEnabledOverrideWithAndAnnotationFlagAndTechProperty() {
validate(
determineEnablement("bar", false, EndpointType.WEB,
"endpoints.bar.web.enabled=true"),
true, "found property endpoints.bar.web.enabled");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointDelivery.WEB, "endpoints.bar.web.enabled=true");
validate(enablement, true, "found property endpoints.bar.web.enabled");
}
@Test
public void specificEnabledOverrideWithAndAnnotationFlagHasNoEffectWithUnrelatedTechProperty() {
validate(
determineEnablement("bar", false, EndpointType.WEB,
"endpoints.bar.jmx.enabled=true"),
false, "endpoint 'bar' (web) is disabled by default");
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointDelivery.WEB, "endpoints.bar.jmx.enabled=true");
validate(enablement, false, "endpoint 'bar' (web) is disabled by default");
}
private EndpointEnablement getEndpointEnablement(String id, boolean enabledByDefault,
String... environment) {
return getEndpointEnablement(id, enabledByDefault, null, environment);
}
private EndpointEnablement getEndpointEnablement(String id, boolean enabledByDefault,
EndpointDelivery delivery, String... environment) {
MockEnvironment env = new MockEnvironment();
TestPropertyValues.of(environment).applyTo(env);
EndpointEnablementProvider provider = new EndpointEnablementProvider(env);
return provider.getEndpointEnablement(id, enabledByDefault, delivery);
}
private void validate(EndpointEnablement enablement, boolean enabled,
@@ -343,17 +349,4 @@ public class EndpointEnablementProviderTests {
}
}
private EndpointEnablement determineEnablement(String id, boolean enabledByDefault,
String... environment) {
return determineEnablement(id, enabledByDefault, null, environment);
}
private EndpointEnablement determineEnablement(String id, boolean enabledByDefault,
EndpointType type, String... environment) {
MockEnvironment env = new MockEnvironment();
TestPropertyValues.of(environment).applyTo(env);
EndpointEnablementProvider provider = new EndpointEnablementProvider(env);
return provider.getEndpointEnablement(id, enabledByDefault, type);
}
}

View File

@@ -22,7 +22,7 @@ import java.util.Map;
import org.junit.Test;
import org.springframework.boot.endpoint.EndpointInfo;
import org.springframework.boot.endpoint.EndpointOperationType;
import org.springframework.boot.endpoint.OperationType;
import org.springframework.boot.endpoint.web.OperationRequestPredicate;
import org.springframework.boot.endpoint.web.WebEndpointHttpMethod;
import org.springframework.boot.endpoint.web.WebEndpointOperation;
@@ -136,7 +136,7 @@ public class RequestMappingEndpointTests {
WebEndpointHttpMethod.GET, Collections.singletonList("application/json"),
Collections.singletonList("application/json"));
WebEndpointOperation operation = new WebEndpointOperation(
EndpointOperationType.READ, (arguments) -> "Invoked", true,
OperationType.READ, (arguments) -> "Invoked", true,
requestPredicate, "test");
WebEndpointServletHandlerMapping mapping = new WebEndpointServletHandlerMapping(
"application", Collections.singleton(new EndpointInfo<>("test", true,