Replace enabledByDefault to DefaultEnablement

This commit introduces a DefaultEnablement enum that replaces the
"enabledByDefault" boolean flag of Endpoint. This allows to better
control what indicates the default enablement of an endpoint.

With DefaultEnablement#ENABLED, the endpoint is enabled unless an
endpoint specific property says otherwise. With DefaultEnabled#DISABLED,
the endpoint is disabled unless an endpoint specific property says
otherwise. DefaultEnablement#NEUTRAL provides a dedicated option to
indicate that we should resort to the default settings in absence of
a specific property.

See gh-10161
pull/10272/head
Stephane Nicoll 7 years ago
parent 6cd624ba39
commit 222ed44bd4

@ -19,9 +19,9 @@ package org.springframework.boot.actuate.autoconfigure.endpoint;
import java.util.Arrays;
import java.util.List;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceOperationParameterMapper;
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;

@ -16,7 +16,8 @@
package org.springframework.boot.actuate.autoconfigure.endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.DefaultEnablement;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert;
@ -42,24 +43,24 @@ public class EndpointEnablementProvider {
* Return the {@link EndpointEnablement} of an endpoint with no specific tech
* exposure.
* @param endpointId the id of the endpoint
* @param enabledByDefault whether the endpoint is enabled by default or not
* @param defaultEnablement the {@link DefaultEnablement} of the endpoint
* @return the {@link EndpointEnablement} of that endpoint
*/
public EndpointEnablement getEndpointEnablement(String endpointId,
boolean enabledByDefault) {
return getEndpointEnablement(endpointId, enabledByDefault, null);
DefaultEnablement defaultEnablement) {
return getEndpointEnablement(endpointId, defaultEnablement, null);
}
/**
* 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 defaultEnablement the {@link DefaultEnablement} of the endpoint
* @param exposure the requested {@link EndpointExposure}
* @return the {@link EndpointEnablement} of that endpoint for the specified
* {@link EndpointExposure}
*/
public EndpointEnablement getEndpointEnablement(String endpointId,
boolean enabledByDefault, EndpointExposure exposure) {
DefaultEnablement defaultEnablement, EndpointExposure exposure) {
Assert.hasText(endpointId, "Endpoint id must have a value");
Assert.isTrue(!endpointId.equals("default"),
"Endpoint id 'default' is a reserved "
@ -74,10 +75,11 @@ public class EndpointEnablementProvider {
}
// All endpoints specific attributes have been looked at. Checking default value
// for the endpoint
if (!enabledByDefault) {
return getDefaultEndpointEnablement(endpointId, false, exposure);
if (defaultEnablement != DefaultEnablement.NEUTRAL) {
return getDefaultEndpointEnablement(endpointId,
(defaultEnablement == DefaultEnablement.ENABLED), exposure);
}
return getGlobalEndpointEnablement(endpointId, enabledByDefault, exposure);
return getGlobalEndpointEnablement(endpointId, defaultEnablement, exposure);
}
private EndpointEnablement findEnablement(String endpointId,
@ -89,7 +91,7 @@ public class EndpointEnablementProvider {
}
private EndpointEnablement getGlobalEndpointEnablement(String endpointId,
boolean enabledByDefault, EndpointExposure exposure) {
DefaultEnablement defaultEnablement, EndpointExposure exposure) {
EndpointEnablement result = findGlobalEndpointEnablement(exposure);
if (result != null) {
return result;
@ -98,7 +100,42 @@ public class EndpointEnablementProvider {
if (result != null) {
return result;
}
return getDefaultEndpointEnablement(endpointId, enabledByDefault, exposure);
boolean enablement = determineGlobalDefaultEnablement(defaultEnablement, exposure);
String message = determineGlobalDefaultMessage(endpointId, enablement, exposure,
defaultEnablement);
return new EndpointEnablement(enablement, message);
}
private boolean determineGlobalDefaultEnablement(DefaultEnablement defaultEnablement,
EndpointExposure exposure) {
if (defaultEnablement == DefaultEnablement.NEUTRAL) {
return exposure == null || exposure.isEnabledByDefault();
}
return (defaultEnablement == DefaultEnablement.ENABLED);
}
private String determineGlobalDefaultMessage(String endpointId, boolean enablement,
EndpointExposure exposure, DefaultEnablement defaultEnablement) {
StringBuilder message = new StringBuilder();
message.append(String.format("endpoint '%s' ", endpointId));
if (exposure != null) {
message.append(String.format("(%s) ", exposure.name().toLowerCase()));
}
message.append(String.format("is %s ", (enablement ? "enabled" : "disabled")));
if (defaultEnablement == DefaultEnablement.NEUTRAL) {
if (exposure != null) {
message.append(String.format("(default for %s endpoints)",
exposure.name().toLowerCase()));
}
else {
message.append("(default)");
}
}
else {
message.append("by default");
}
return message.toString();
}
private EndpointEnablement findGlobalEndpointEnablement(EndpointExposure exposure) {

@ -20,9 +20,9 @@ import java.util.Collection;
import java.util.stream.Collectors;
import org.springframework.boot.actuate.endpoint.EndpointDiscoverer;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.Operation;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.core.env.Environment;
/**
@ -61,7 +61,7 @@ public class EndpointProvider<T extends Operation> {
private boolean isEnabled(EndpointInfo<?> endpoint) {
return this.endpointEnablementProvider.getEndpointEnablement(endpoint.getId(),
endpoint.isEnabledByDefault(), this.exposure).isEnabled();
endpoint.getDefaultEnablement(), this.exposure).isEnabled();
}
}

@ -22,22 +22,39 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.actuate.endpoint.DefaultEnablement;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.context.annotation.Conditional;
/**
* {@link Conditional} that checks whether an endpoint is enabled or not. Matches
* according to the {@code enabledByDefault} flag {@code types} flag that the
* according to the {@code defaultEnablement} and {@code types} flag that the
* {@link Endpoint} may be restricted to.
* <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 EndpointExposure}, if any. If any property are set, they are evaluated
* with a sensible order of precedence.
* When an endpoint uses {@link DefaultEnablement#DISABLED}, it will only be enabled if
* {@code endpoint.<name>.enabled}, {@code endpoint.<name>.jmx.enabled} or
* {@code endpoint.<name>.web.enabled} is {@code true}.
* <p>
* When an endpoint uses {@link DefaultEnablement#ENABLED}, it will be enabled unless
* {@code endpoint.<name>.enabled}, {@code endpoint.<name>.jmx.enabled} or
* {@code endpoint.<name>.web.enabled} is {@code false}.
* <p>
* When an endpoint uses {@link DefaultEnablement#NEUTRAL}, it will be enabled if
* {@code endpoint.default.enabled}, {@code endpoint.default.jmx.enabled} or
* {@code endpoint.default.web.enabled} is {@code true} and
* {@code endpoint.<name>.enabled}, {@code endpoint.<name>.jmx.enabled} or
* {@code endpoint.<name>.web.enabled} has not been set to {@code false}.
* <p>
* If any properties are set, they are evaluated from most to least specific, e.g.
* considering a web endpoint with id {@code foo}:
* <ol>
* <li>endpoints.foo.web.enabled</li>
* <li>endpoints.foo.enabled</li>
* <li>endpoints.default.web.enabled</li>
* <li>endpoints.default.enabled</li>
* </ol>
* For instance if {@code endpoints.default.enabled} is {@code false} but
* {@code endpoints.<id>.enabled} is {@code true}, the condition will match.
* {@code endpoints.<name>.enabled} is {@code true}, the condition will match.
* <p>
* This condition must be placed on a {@code @Bean} method producing an endpoint as its id
* and other attributes are inferred from the {@link Endpoint} annotation set on the
@ -53,7 +70,7 @@ import org.springframework.context.annotation.Conditional;
* ...
* }
*
* &#064;Endpoint(id = "my", enabledByDefault = false)
* &#064;Endpoint(id = "my", defaultEnablement = DefaultEnablement.DISABLED)
* static class MyEndpoint { ... }
*
* }</pre>

@ -18,8 +18,9 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.condition;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointEnablement;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointEnablementProvider;
import org.springframework.boot.actuate.endpoint.DefaultEnablement;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxEndpointExtension;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointExtension;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
@ -106,7 +107,7 @@ class OnEnabledEndpointCondition extends SpringBootCondition {
}
// If both types are set, all exposure technologies are exposed
EndpointExposure[] exposures = endpoint.exposure();
return new EndpointAttributes(endpoint.id(), endpoint.enabledByDefault(),
return new EndpointAttributes(endpoint.id(), endpoint.defaultEnablement(),
(exposures.length == 1 ? exposures[0] : null));
}
@ -114,21 +115,23 @@ class OnEnabledEndpointCondition extends SpringBootCondition {
private final String id;
private final boolean enabled;
private final DefaultEnablement defaultEnablement;
private final EndpointExposure exposure;
EndpointAttributes(String id, boolean enabled, EndpointExposure exposure) {
EndpointAttributes(String id, DefaultEnablement defaultEnablement,
EndpointExposure exposure) {
if (!StringUtils.hasText(id)) {
throw new IllegalStateException("Endpoint id could not be determined");
}
this.id = id;
this.enabled = enabled;
this.defaultEnablement = defaultEnablement;
this.exposure = exposure;
}
public EndpointEnablement getEnablement(EndpointEnablementProvider provider) {
return provider.getEndpointEnablement(this.id, this.enabled, this.exposure);
return provider.getEndpointEnablement(this.id, this.defaultEnablement,
this.exposure);
}
}

@ -23,9 +23,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.endpoint.DefaultCachingConfigurationFactory;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointProvider;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanRegistrar;
import org.springframework.boot.actuate.endpoint.jmx.JmxEndpointOperation;
import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxAnnotationEndpointDiscoverer;

@ -20,7 +20,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.DefaultEnablement;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.util.ObjectUtils;
@ -38,306 +39,238 @@ public class EndpointEnablementProviderTests {
public ExpectedException thrown = ExpectedException.none();
@Test
public void cannotDetermineEnablementWithEmptyEndpoint() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Endpoint id must have a value");
getEndpointEnablement(" ", true);
public void defaultEnablementDisabled() {
EndpointEnablement enablement = getEndpointEnablement("foo",
DefaultEnablement.DISABLED);
validate(enablement, false, "endpoint 'foo' is disabled by default");
}
@Test
public void cannotDetermineEnablementOfEndpointAll() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Endpoint id 'default' is a reserved value and cannot "
+ "be used by an endpoint");
getEndpointEnablement("default", true);
public void defaultEnablementDisabledWithGeneralEnablement() {
EndpointEnablement enablement = getEndpointEnablement("foo",
DefaultEnablement.DISABLED, "endpoints.default.enabled=true");
validate(enablement, false, "endpoint 'foo' is disabled by default");
}
@Test
public void generalEnabledByDefault() {
EndpointEnablement enablement = getEndpointEnablement("foo", true);
validate(enablement, true, "endpoint 'foo' is enabled by default");
}
@Test
public void generalDisabledViaSpecificProperty() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
"endpoints.foo.enabled=false");
validate(enablement, false, "found property endpoints.foo.enabled");
}
@Test
public void generalDisabledViaGeneralProperty() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
"endpoints.default.enabled=false");
validate(enablement, false, "found property endpoints.default.enabled");
public void defaultEnablementDisabledWithGeneralTechEnablement() {
EndpointEnablement enablement = getEndpointEnablement("foo",
DefaultEnablement.DISABLED, EndpointExposure.WEB,
"endpoints.default.web.enabled=true");
validate(enablement, false, "endpoint 'foo' (web) is disabled by default");
}
@Test
public void generalEnabledOverrideViaSpecificProperty() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
"endpoints.default.enabled=false", "endpoints.foo.enabled=true");
public void defaultEnablementDisabledWithOverride() {
EndpointEnablement enablement = getEndpointEnablement("foo",
DefaultEnablement.DISABLED, "endpoints.foo.enabled=true");
validate(enablement, true, "found property endpoints.foo.enabled");
}
@Test
public void generalEnabledOverrideViaSpecificWebProperty() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
"endpoints.foo.enabled=false", "endpoints.foo.web.enabled=true");
public void defaultEnablementDisabledWithTechOverride() {
EndpointEnablement enablement = getEndpointEnablement("foo",
DefaultEnablement.DISABLED, EndpointExposure.WEB,
"endpoints.foo.web.enabled=true");
validate(enablement, true, "found property endpoints.foo.web.enabled");
}
@Test
public void generalEnabledOverrideViaSpecificJmxProperty() {
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(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() {
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() {
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() {
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() {
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() {
EndpointEnablement enablement = getEndpointEnablement("bar", false);
validate(enablement, false, "endpoint 'bar' is disabled by default");
}
@Test
public void generalDisabledByDefaultWithAnnotationFlagEvenWithGeneralProperty() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.default.enabled=true");
validate(enablement, false, "endpoint 'bar' is disabled by default");
}
@Test
public void generalDisabledByDefaultWithAnnotationFlagEvenWithGeneralWebProperty() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.default.web.enabled=true");
validate(enablement, false, "endpoint 'bar' is disabled by default");
}
@Test
public void generalDisabledByDefaultWithAnnotationFlagEvenWithGeneralJmxProperty() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.default.jmx.enabled=true");
validate(enablement, false, "endpoint 'bar' is disabled by default");
public void defaultEnablementDisabledWithIrrelevantTechOverride() {
EndpointEnablement enablement = getEndpointEnablement("foo",
DefaultEnablement.DISABLED, EndpointExposure.WEB,
"endpoints.foo.jmx.enabled=true");
validate(enablement, false, "endpoint 'foo' (web) is disabled by default");
}
@Test
public void generalEnabledOverrideWithAndAnnotationFlagAndSpecificProperty() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.bar.enabled=true");
validate(enablement, true, "found property endpoints.bar.enabled");
public void defaultEnablementEnabled() {
EndpointEnablement enablement = getEndpointEnablement("bar",
DefaultEnablement.ENABLED);
validate(enablement, true, "endpoint 'bar' is enabled by default");
}
@Test
public void generalEnabledOverrideWithAndAnnotationFlagAndSpecificWebProperty() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.bar.web.enabled=true");
validate(enablement, true, "found property endpoints.bar.web.enabled");
public void defaultEnablementEnabledWithGeneralDisablement() {
EndpointEnablement enablement = getEndpointEnablement("bar",
DefaultEnablement.ENABLED, "endpoints.default.enabled=false");
validate(enablement, true, "endpoint 'bar' is enabled by default");
}
@Test
public void generalEnabledOverrideWithAndAnnotationFlagAndSpecificJmxProperty() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.bar.jmx.enabled=true");
validate(enablement, true, "found property endpoints.bar.jmx.enabled");
public void defaultEnablementEnabledWithGeneralTechDisablement() {
EndpointEnablement enablement = getEndpointEnablement("bar",
DefaultEnablement.ENABLED, EndpointExposure.JMX,
"endpoints.default.jmx.enabled=false");
validate(enablement, true, "endpoint 'bar' (jmx) is enabled by default");
}
@Test
public void generalEnabledOverrideWithAndAnnotationFlagAndAnyProperty() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
"endpoints.bar.web.enabled=false", "endpoints.bar.jmx.enabled=true");
validate(enablement, true, "found property endpoints.bar.jmx.enabled");
public void defaultEnablementEnabledWithOverride() {
EndpointEnablement enablement = getEndpointEnablement("bar",
DefaultEnablement.ENABLED, "endpoints.bar.enabled=false");
validate(enablement, false, "found property endpoints.bar.enabled");
}
@Test
public void specificEnabledByDefault() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointExposure.JMX);
validate(enablement, true, "endpoint 'foo' (jmx) is enabled by default");
public void defaultEnablementEnabledWithTechOverride() {
EndpointEnablement enablement = getEndpointEnablement("bar",
DefaultEnablement.ENABLED, EndpointExposure.JMX,
"endpoints.bar.jmx.enabled=false");
validate(enablement, false, "found property endpoints.bar.jmx.enabled");
}
@Test
public void specificDisabledViaEndpointProperty() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointExposure.WEB, "endpoints.foo.enabled=false");
validate(enablement, false, "found property endpoints.foo.enabled");
public void defaultEnablementEnabledWithIrrelevantTechOverride() {
EndpointEnablement enablement = getEndpointEnablement("bar",
DefaultEnablement.ENABLED, EndpointExposure.JMX,
"endpoints.bar.web.enabled=false");
validate(enablement, true, "endpoint 'bar' (jmx) is enabled by default");
}
@Test
public void specificDisabledViaTechProperty() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointExposure.WEB, "endpoints.foo.web.enabled=false");
validate(enablement, false, "found property endpoints.foo.web.enabled");
public void defaultEnablementNeutral() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL);
validate(enablement, true,
"endpoint 'biz' is enabled (default)");
}
@Test
public void specificNotDisabledViaUnrelatedTechProperty() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointExposure.JMX, "endpoints.foo.web.enabled=false");
validate(enablement, true, "endpoint 'foo' (jmx) is enabled by default");
public void defaultEnablementNeutralWeb() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.WEB);
validate(enablement, false,
"endpoint 'default' (web) is disabled by default");
}
@Test
public void specificDisabledViaGeneralProperty() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointExposure.JMX, "endpoints.default.enabled=false");
validate(enablement, false, "found property endpoints.default.enabled");
public void defaultEnablementNeutralJmx() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX);
validate(enablement, true,
"endpoint 'biz' (jmx) is enabled (default for jmx endpoints)");
}
@Test
public void specificEnabledOverrideViaEndpointProperty() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointExposure.WEB, "endpoints.default.enabled=false",
"endpoints.foo.enabled=true");
validate(enablement, true, "found property endpoints.foo.enabled");
public void defaultEnablementNeutralWithGeneralDisablement() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, "endpoints.default.enabled=false");
validate(enablement, false,
"found property endpoints.default.enabled");
}
@Test
public void specificEnabledOverrideViaTechProperty() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointExposure.WEB, "endpoints.foo.enabled=false",
"endpoints.foo.web.enabled=true");
validate(enablement, true, "found property endpoints.foo.web.enabled");
public void defaultEnablementNeutralWebWithTechDisablement() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.default.jmx.enabled=false");
validate(enablement, false,
"found property endpoints.default.jmx.enabled");
}
@Test
public void specificEnabledOverrideHasNotEffectWithUnrelatedTechProperty() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointExposure.WEB, "endpoints.foo.enabled=false",
"endpoints.foo.jmx.enabled=true");
validate(enablement, false, "found property endpoints.foo.enabled");
public void defaultEnablementNeutralTechTakesPrecedence() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.default.enabled=true",
"endpoints.default.jmx.enabled=false");
validate(enablement, false,
"found property endpoints.default.jmx.enabled");
}
@Test
public void specificEnabledOverrideViaGeneralWebProperty() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointExposure.WEB, "endpoints.default.enabled=false",
public void defaultEnablementNeutralWebWithTechEnablement() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.WEB,
"endpoints.default.web.enabled=true");
validate(enablement, true, "found property endpoints.default.web.enabled");
}
@Test
public void specificEnabledOverrideHasNoEffectWithUnrelatedTechProperty() {
validate(getEndpointEnablement("foo", true, EndpointExposure.JMX,
"endpoints.default.enabled=false", "endpoints.default.web.enabled=true"),
false, "found property endpoints.default.enabled");
}
@Test
public void specificDisabledWithEndpointPropertyEvenWithEnabledGeneralProperties() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointExposure.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");
validate(enablement, true,
"found property endpoints.default.web.enabled");
}
@Test
public void specificDisabledWithTechPropertyEvenWithEnabledGeneralProperties() {
EndpointEnablement enablement = getEndpointEnablement("foo", true,
EndpointExposure.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");
public void defaultEnablementNeutralWebWithUnrelatedTechDisablement() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.default.web.enabled=false");
validate(enablement, true,
"endpoint 'biz' (jmx) is enabled (default for jmx endpoints)");
}
@Test
public void specificDisabledByDefaultWithAnnotationFlag() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointExposure.WEB);
validate(enablement, false, "endpoint 'bar' (web) is disabled by default");
public void defaultEnablementNeutralWithOverride() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, "endpoints.biz.enabled=false");
validate(enablement, false,
"found property endpoints.biz.enabled");
}
@Test
public void specificDisabledByDefaultWithAnnotationFlagEvenWithGeneralProperty() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointExposure.WEB, "endpoints.default.enabled=true");
validate(enablement, false, "endpoint 'bar' (web) is disabled by default");
public void defaultEnablementNeutralWebWithOverride() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.WEB,
"endpoints.biz.web.enabled=true");
validate(enablement, true,
"found property endpoints.biz.web.enabled");
}
@Test
public void specificDisabledByDefaultWithAnnotationFlagEvenWithGeneralWebProperty() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointExposure.WEB, "endpoints.default.web.enabled=true");
validate(enablement, false, "endpoint 'bar' (web) is disabled by default");
public void defaultEnablementNeutralJmxWithOverride() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.biz.jmx.enabled=false");
validate(enablement, false,
"found property endpoints.biz.jmx.enabled");
}
@Test
public void specificDisabledByDefaultWithAnnotationFlagEvenWithGeneralJmxProperty() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointExposure.WEB, "endpoints.default.jmx.enabled=true");
validate(enablement, false, "endpoint 'bar' (web) is disabled by default");
public void defaultEnablementNeutralTechTakesPrecedenceOnEverything() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.default.enabled=false",
"endpoints.default.jmx.enabled=false",
"endpoints.biz.enabled=false",
"endpoints.biz.jmx.enabled=true");
validate(enablement, true,
"found property endpoints.biz.jmx.enabled");
}
@Test
public void specificEnabledOverrideWithAndAnnotationFlagAndEndpointProperty() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointExposure.WEB, "endpoints.bar.enabled=true");
validate(enablement, true, "found property endpoints.bar.enabled");
public void defaultEnablementNeutralSpecificTakesPrecedenceOnDefaults() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.default.enabled=false",
"endpoints.default.jmx.enabled=false",
"endpoints.biz.enabled=true");
validate(enablement, true,
"found property endpoints.biz.enabled");
}
@Test
public void specificEnabledOverrideWithAndAnnotationFlagAndTechProperty() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointExposure.WEB, "endpoints.bar.web.enabled=true");
validate(enablement, true, "found property endpoints.bar.web.enabled");
}
@Test
public void specificEnabledOverrideWithAndAnnotationFlagHasNoEffectWithUnrelatedTechProperty() {
EndpointEnablement enablement = getEndpointEnablement("bar", false,
EndpointExposure.WEB, "endpoints.bar.jmx.enabled=true");
validate(enablement, false, "endpoint 'bar' (web) is disabled by default");
public void defaultEnablementNeutralDefaultTechTakesPrecedenceOnGeneralDefault() {
EndpointEnablement enablement = getEndpointEnablement("biz",
DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.default.enabled=false",
"endpoints.default.jmx.enabled=true");
validate(enablement, true,
"found property endpoints.default.jmx.enabled");
}
private EndpointEnablement getEndpointEnablement(String id, boolean enabledByDefault,
String... environment) {
private EndpointEnablement getEndpointEnablement(String id,
DefaultEnablement enabledByDefault, String... environment) {
return getEndpointEnablement(id, enabledByDefault, null, environment);
}
private EndpointEnablement getEndpointEnablement(String id, boolean enabledByDefault,
EndpointExposure exposure, String... environment) {
private EndpointEnablement getEndpointEnablement(String id,
DefaultEnablement enabledByDefault, EndpointExposure exposure,
String... environment) {
MockEnvironment env = new MockEnvironment();
TestPropertyValues.of(environment).applyTo(env);
EndpointEnablementProvider provider = new EndpointEnablementProvider(env);
return provider.getEndpointEnablement(id, enabledByDefault, exposure);
if (exposure != null) {
return provider.getEndpointEnablement(id, enabledByDefault, exposure);
}
return provider.getEndpointEnablement(id, enabledByDefault);
}
private void validate(EndpointEnablement enablement, boolean enabled,

@ -18,8 +18,9 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.condition;
import org.junit.Test;
import org.springframework.boot.actuate.endpoint.DefaultEnablement;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxEndpointExtension;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointExtension;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@ -297,7 +298,7 @@ public class ConditionalOnEnabledEndpointTests {
}
@Endpoint(id = "bar", exposure = { EndpointExposure.WEB,
EndpointExposure.JMX }, enabledByDefault = false)
EndpointExposure.JMX }, defaultEnablement = DefaultEnablement.DISABLED)
static class BarEndpoint {
}

@ -27,6 +27,7 @@ import org.mockito.MockitoAnnotations;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointProvider;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties;
import org.springframework.boot.actuate.endpoint.DefaultEnablement;
import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.web.WebEndpointOperation;
@ -82,8 +83,10 @@ public class DefaultEndpointPathProviderTests {
private DefaultEndpointPathProvider createProvider(String contextPath) {
Collection<EndpointInfo<WebEndpointOperation>> endpoints = new ArrayList<>();
endpoints.add(new EndpointInfo<>("foo", true, Collections.emptyList()));
endpoints.add(new EndpointInfo<>("bar", true, Collections.emptyList()));
endpoints.add(new EndpointInfo<>("foo", DefaultEnablement.ENABLED,
Collections.emptyList()));
endpoints.add(new EndpointInfo<>("bar", DefaultEnablement.ENABLED,
Collections.emptyList()));
given(this.endpointProvider.getEndpoints()).willReturn(endpoints);
ManagementServerProperties managementServerProperties = new ManagementServerProperties();
managementServerProperties.setContextPath(contextPath);

@ -21,6 +21,7 @@ import java.util.Map;
import org.junit.Test;
import org.springframework.boot.actuate.endpoint.DefaultEnablement;
import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.OperationType;
import org.springframework.boot.actuate.endpoint.web.OperationRequestPredicate;
@ -140,8 +141,8 @@ public class RequestMappingEndpointTests {
(arguments) -> "Invoked", true, requestPredicate, "test");
WebMvcEndpointHandlerMapping mapping = new WebMvcEndpointHandlerMapping(
new EndpointMapping("application"),
Collections.singleton(new EndpointInfo<>("test", true,
Collections.singleton(operation))));
Collections.singleton(new EndpointInfo<>("test",
DefaultEnablement.ENABLED, Collections.singleton(operation))));
mapping.setApplicationContext(new StaticApplicationContext());
mapping.afterPropertiesSet();
return mapping;

@ -20,6 +20,7 @@ import java.util.Collections;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.boot.actuate.endpoint.DefaultEnablement;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.context.ApplicationContext;
@ -34,7 +35,7 @@ import org.springframework.context.ConfigurableApplicationContext;
* @author Andy Wilkinson
* @since 2.0.0
*/
@Endpoint(id = "shutdown", enabledByDefault = false)
@Endpoint(id = "shutdown", defaultEnablement = DefaultEnablement.DISABLED)
public class ShutdownEndpoint implements ApplicationContextAware {
private static final Map<String, Object> NO_CONTEXT_MESSAGE = Collections

@ -0,0 +1,42 @@
/*
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.endpoint;
/**
* Enumerate the enablement options for an endpoint.
*
* @author Stephane Nicoll
* @since 2.0.0
*/
public enum DefaultEnablement {
/**
* The endpoint is enabled unless explicitly disabled.
*/
ENABLED,
/**
* The endpoint is disabled unless explicitly enabled.
*/
DISABLED,
/**
* The endpoint's enablement defaults to the "default" settings.
*/
NEUTRAL
}

@ -14,10 +14,10 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.endpoint.annotation;
package org.springframework.boot.actuate.endpoint;
/**
* An enumeration of the available {@link Endpoint} exposure technologies.
* An enumeration of the available exposure technologies for an endpoint.
*
* @author Stephane Nicoll
* @since 2.0.0

@ -29,7 +29,7 @@ public class EndpointInfo<T extends Operation> {
private final String id;
private final boolean enabledByDefault;
private final DefaultEnablement defaultEnablement;
private final Collection<T> operations;
@ -37,12 +37,13 @@ public class EndpointInfo<T extends Operation> {
* Creates a new {@code EndpointInfo} describing an endpoint with the given {@code id}
* and {@code operations}.
* @param id the id of the endpoint
* @param enabledByDefault whether or not the endpoint is enabled by default
* @param defaultEnablement the {@link DefaultEnablement} of the endpoint
* @param operations the operations of the endpoint
*/
public EndpointInfo(String id, boolean enabledByDefault, Collection<T> operations) {
public EndpointInfo(String id, DefaultEnablement defaultEnablement,
Collection<T> operations) {
this.id = id;
this.enabledByDefault = enabledByDefault;
this.defaultEnablement = defaultEnablement;
this.operations = operations;
}
@ -55,11 +56,11 @@ public class EndpointInfo<T extends Operation> {
}
/**
* Returns whether or not this endpoint is enabled by default.
* @return {@code true} if it is enabled by default, otherwise {@code false}
* Return the {@link DefaultEnablement} of the endpoint.
* @return the default enablement
*/
public boolean isEnabledByDefault() {
return this.enabledByDefault;
public DefaultEnablement getDefaultEnablement() {
return this.defaultEnablement;
}
/**

@ -29,7 +29,9 @@ import java.util.function.Consumer;
import java.util.function.Function;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.boot.actuate.endpoint.DefaultEnablement;
import org.springframework.boot.actuate.endpoint.EndpointDiscoverer;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.Operation;
import org.springframework.boot.actuate.endpoint.OperationType;
@ -117,9 +119,10 @@ public abstract class AnnotationEndpointDiscoverer<T extends Operation, K>
private EndpointInfo<T> createEndpointInfo(String beanName, Class<?> beanType,
AnnotationAttributes attributes) {
String id = attributes.getString("id");
boolean enabledByDefault = attributes.getBoolean("enabledByDefault");
DefaultEnablement defaultEnablement = (DefaultEnablement) attributes.get(
"defaultEnablement");
Map<Method, T> operations = discoverOperations(id, beanName, beanType);
return new EndpointInfo<>(id, enabledByDefault, operations.values());
return new EndpointInfo<>(id, defaultEnablement, operations.values());
}
private Map<Class<?>, EndpointExtensionInfo<T>> discoverExtensions(
@ -192,7 +195,7 @@ public abstract class AnnotationEndpointDiscoverer<T extends Operation, K>
.put(this.operationKeyFactory.apply(operation), operation);
endpoint.getOperations().forEach(consumer);
extension.getOperations().forEach(consumer);
return new EndpointInfo<>(endpoint.getId(), endpoint.isEnabledByDefault(),
return new EndpointInfo<>(endpoint.getId(), endpoint.getDefaultEnablement(),
operations.values());
}

@ -22,14 +22,15 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.actuate.endpoint.EndpointDiscoverer;
import org.springframework.boot.actuate.endpoint.DefaultEnablement;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
/**
* Identifies a type as being an endpoint.
*
* @author Andy Wilkinson
* @since 2.0.0
* @see EndpointDiscoverer
* @see AnnotationEndpointDiscoverer
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ -50,9 +51,10 @@ public @interface Endpoint {
EndpointExposure[] exposure() default {};
/**
* Whether or not the endpoint is enabled by default.
* @return {@code true} if the endpoint is enabled by default, otherwise {@code false}
* Defines the {@link DefaultEnablement} of the endpoint. By default, the endpoint's
* enablement defaults to the "default" settings.
* @return the default enablement
*/
boolean enabledByDefault() default true;
DefaultEnablement defaultEnablement() default DefaultEnablement.NEUTRAL;
}

@ -26,6 +26,7 @@ import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.OperationInvoker;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper;
@ -33,7 +34,6 @@ import org.springframework.boot.actuate.endpoint.OperationType;
import org.springframework.boot.actuate.endpoint.ReflectiveOperationInvoker;
import org.springframework.boot.actuate.endpoint.annotation.AnnotationEndpointDiscoverer;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration;
import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory;
import org.springframework.boot.actuate.endpoint.cache.CachingOperationInvoker;

@ -27,6 +27,7 @@ import java.util.stream.Stream;
import org.reactivestreams.Publisher;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.OperationInvoker;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper;
@ -34,7 +35,6 @@ import org.springframework.boot.actuate.endpoint.OperationType;
import org.springframework.boot.actuate.endpoint.ReflectiveOperationInvoker;
import org.springframework.boot.actuate.endpoint.annotation.AnnotationEndpointDiscoverer;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration;
import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory;

@ -21,8 +21,8 @@ import java.io.File;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.logging.LogFile;

@ -36,8 +36,8 @@ import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
import org.springframework.boot.context.properties.ConfigurationProperties;

@ -25,6 +25,7 @@ import javax.management.MBeanParameterInfo;
import org.junit.Test;
import org.springframework.boot.actuate.endpoint.DefaultEnablement;
import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.OperationInvoker;
import org.springframework.boot.actuate.endpoint.OperationType;
@ -47,8 +48,8 @@ public class EndpointMBeanInfoAssemblerTests {
JmxEndpointOperation operation = new JmxEndpointOperation(OperationType.READ,
new DummyOperationInvoker(), "getAll", Object.class, "Test operation",
Collections.emptyList());
EndpointInfo<JmxEndpointOperation> endpoint = new EndpointInfo<>("test", true,
Collections.singletonList(operation));
EndpointInfo<JmxEndpointOperation> endpoint = new EndpointInfo<>("test",
DefaultEnablement.ENABLED, Collections.singletonList(operation));
EndpointMBeanInfo endpointMBeanInfo = this.mBeanInfoAssembler
.createEndpointMBeanInfo(endpoint);
assertThat(endpointMBeanInfo).isNotNull();
@ -77,8 +78,8 @@ public class EndpointMBeanInfoAssemblerTests {
new DummyOperationInvoker(), "update", Object.class, "Update operation",
Collections.singletonList(new JmxEndpointOperationParameterInfo("test",
String.class, "Test argument")));
EndpointInfo<JmxEndpointOperation> endpoint = new EndpointInfo<>("another", true,
Collections.singletonList(operation));
EndpointInfo<JmxEndpointOperation> endpoint = new EndpointInfo<>("another",
DefaultEnablement.ENABLED, Collections.singletonList(operation));
EndpointMBeanInfo endpointMBeanInfo = this.mBeanInfoAssembler
.createEndpointMBeanInfo(endpoint);
assertThat(endpointMBeanInfo).isNotNull();

@ -26,11 +26,11 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.ReflectiveOperationInvoker;
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration;

@ -23,6 +23,7 @@ import java.util.Map;
import org.assertj.core.api.Condition;
import org.junit.Test;
import org.springframework.boot.actuate.endpoint.DefaultEnablement;
import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.OperationType;
@ -59,7 +60,8 @@ public class EndpointLinksResolverTests {
public void resolvedLinksContainsALinkForEachEndpointOperation() {
Map<String, Link> links = this.linksResolver
.resolveLinks(
Arrays.asList(new EndpointInfo<>("alpha", true,
Arrays.asList(new EndpointInfo<>("alpha",
DefaultEnablement.ENABLED,
Arrays.asList(operationWithPath("/alpha", "alpha"),
operationWithPath("/alpha/{name}",
"alpha-name")))),

@ -32,11 +32,11 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.OperationInvoker;
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;

@ -1074,28 +1074,28 @@ content into your application; rather pick only the properties that you need.
# AUDIT EVENTS ENDPOINT ({sc-spring-boot-actuator}/endpoint/AuditEventsEndpoint.{sc-ext}[AuditEventsEndpoint])
endpoints.auditevents.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.auditevents.enabled=true # Enable the auditevents endpoint.
endpoints.auditevents.jmx.enabled=true # Expose the auditevents endpoint as a JMX MBean.
endpoints.auditevents.web.enabled=false # Expose the auditevents endpoint as a Web endpoint.
endpoints.auditevents.enabled= # Enable the auditevents endpoint.
endpoints.auditevents.jmx.enabled= # Expose the auditevents endpoint as a JMX MBean.
endpoints.auditevents.web.enabled= # Expose the auditevents endpoint as a Web endpoint.
# AUTO-CONFIGURATION REPORT ENDPOINT ({sc-spring-boot-actuator}/endpoint/AutoConfigurationReportEndpoint.{sc-ext}[AutoConfigurationReportEndpoint])
endpoints.autoconfig.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.autoconfig.enabled=true # Enable the autoconfig endpoint.
endpoints.autoconfig.jmx.enabled=true # Expose the autoconfig endpoint as a JMX MBean.
endpoints.autoconfig.web.enabled=false # Expose the autoconfig endpoint as a Web endpoint.
endpoints.autoconfig.enabled= # Enable the autoconfig endpoint.
endpoints.autoconfig.jmx.enabled= # Expose the autoconfig endpoint as a JMX MBean.
endpoints.autoconfig.web.enabled= # Expose the autoconfig endpoint as a Web endpoint.
# BEANS ENDPOINT ({sc-spring-boot-actuator}/endpoint/BeansEndpoint.{sc-ext}[BeansEndpoint])
endpoints.beans.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.beans.enabled=true # Enable the beans endpoint.
endpoints.beans.jmx.enabled=true # Expose the beans endpoint as a JMX MBean.
endpoints.beans.web.enabled=false # Expose the beans endpoint as a Web endpoint.
endpoints.beans.enabled= # Enable the beans endpoint.
endpoints.beans.jmx.enabled= # Expose the beans endpoint as a JMX MBean.
endpoints.beans.web.enabled= # Expose the beans endpoint as a Web endpoint.
# CONFIGURATION PROPERTIES REPORT ENDPOINT ({sc-spring-boot-actuator}/endpoint/ConfigurationPropertiesReportEndpoint.{sc-ext}[ConfigurationPropertiesReportEndpoint])
endpoints.configprops.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.configprops.enabled=true # Enable the configprops endpoint.
endpoints.configprops.jmx.enabled=true # Expose the configprops endpoint as a JMX MBean.
endpoints.configprops.enabled= # Enable the configprops endpoint.
endpoints.configprops.jmx.enabled= # Expose the configprops endpoint as a JMX MBean.
endpoints.configprops.keys-to-sanitize=password,secret,key,token,.*credentials.*,vcap_services # Keys that should be sanitized. Keys can be simple strings that the property ends with or regex expressions.
endpoints.configprops.web.enabled=false # Expose the configprops endpoint as a Web endpoint.
endpoints.configprops.web.enabled= # Expose the configprops endpoint as a Web endpoint.
# ENDPOINT DEFAULT SETTINGS
endpoints.default.enabled=true # Enable all endpoints by default.
@ -1104,63 +1104,63 @@ content into your application; rather pick only the properties that you need.
# ENVIRONMENT ENDPOINT ({sc-spring-boot-actuator}/endpoint/EnvironmentEndpoint.{sc-ext}[EnvironmentEndpoint])
endpoints.env.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.env.enabled=true # Enable the env endpoint.
endpoints.env.jmx.enabled=true # Expose the env endpoint as a JMX MBean.
endpoints.env.enabled= # Enable the env endpoint.
endpoints.env.jmx.enabled= # Expose the env endpoint as a JMX MBean.
endpoints.env.keys-to-sanitize=password,secret,key,token,.*credentials.*,vcap_services # Keys that should be sanitized. Keys can be simple strings that the property ends with or regex expressions.
endpoints.env.web.enabled=false # Expose the env endpoint as a Web endpoint.
endpoints.env.web.enabled= # Expose the env endpoint as a Web endpoint.
# FLYWAY ENDPOINT ({sc-spring-boot-actuator}/endpoint/FlywayEndpoint.{sc-ext}[FlywayEndpoint])
endpoints.flyway.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.flyway.enabled=true # Enable the flyway endpoint.
endpoints.flyway.jmx.enabled=true # Expose the flyway endpoint as a JMX MBean.
endpoints.flyway.web.enabled=false # Expose the flyway endpoint as a Web endpoint.
endpoints.flyway.enabled= # Enable the flyway endpoint.
endpoints.flyway.jmx.enabled= # Expose the flyway endpoint as a JMX MBean.
endpoints.flyway.web.enabled= # Expose the flyway endpoint as a Web endpoint.
# HEALTH ENDPOINT ({sc-spring-boot-actuator}/endpoint/HealthEndpoint.{sc-ext}[HealthEndpoint])
endpoints.health.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.health.enabled=true # Enable the health endpoint.
endpoints.health.jmx.enabled=true # Expose the health endpoint as a JMX MBean.
endpoints.health.web.enabled=false # Expose the health endpoint as a Web endpoint.
endpoints.health.enabled= # Enable the health endpoint.
endpoints.health.jmx.enabled= # Expose the health endpoint as a JMX MBean.
endpoints.health.web.enabled= # Expose the health endpoint as a Web endpoint.
# HEAP DUMP ENDPOINT ({sc-spring-boot-actuator}/endpoint/web/HeapDumpWebEndpoint.{sc-ext}[HeapDumpWebEndpoint])
endpoints.heapdump.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.heapdump.enabled=true # Enable the heapdump endpoint.
endpoints.heapdump.web.enabled=false # Expose the heapdump endpoint as a Web endpoint.
endpoints.heapdump.enabled= # Enable the heapdump endpoint.
endpoints.heapdump.web.enabled= # Expose the heapdump endpoint as a Web endpoint.
# INFO ENDPOINT ({sc-spring-boot-actuator}/endpoint/InfoEndpoint.{sc-ext}[InfoEndpoint])
endpoints.info.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.info.enabled=true # Enable the info endpoint.
endpoints.info.jmx.enabled=true # Expose the info endpoint as a JMX MBean.
endpoints.info.web.enabled=false # Expose the info endpoint as a Web endpoint.
endpoints.info.enabled= # Enable the info endpoint.
endpoints.info.jmx.enabled= # Expose the info endpoint as a JMX MBean.
endpoints.info.web.enabled= # Expose the info endpoint as a Web endpoint.
# LIQUIBASE ENDPOINT ({sc-spring-boot-actuator}/endpoint/LiquibaseEndpoint.{sc-ext}[LiquibaseEndpoint])
endpoints.liquibase.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.liquibase.enabled=true # Enable the liquibase endpoint.
endpoints.liquibase.jmx.enabled=true # Expose the liquibase endpoint as a JMX MBean.
endpoints.liquibase.web.enabled=false # Expose the liquibase endpoint as a Web endpoint.
endpoints.liquibase.enabled= # Enable the liquibase endpoint.
endpoints.liquibase.jmx.enabled= # Expose the liquibase endpoint as a JMX MBean.
endpoints.liquibase.web.enabled= # Expose the liquibase endpoint as a Web endpoint.
# LOG FILE ENDPOINT ({sc-spring-boot-actuator}/endpoint/web/LogFileWebEndpoint.{sc-ext}[LogFileWebEndpoint])
endpoints.logfile.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.logfile.enabled=true # Enable the logfile endpoint.
endpoints.logfile.enabled= # Enable the logfile endpoint.
endpoints.logfile.external-file= # External Logfile to be accessed. Can be used if the logfile is written by output redirect and not by the logging system itself.
endpoints.logfile.web.enabled=false # Expose the logfile endpoint as a Web endpoint.
endpoints.logfile.web.enabled= # Expose the logfile endpoint as a Web endpoint.
# LOGGERS ENDPOINT ({sc-spring-boot-actuator}/endpoint/LoggersEndpoint.{sc-ext}[LoggersEndpoint])
endpoints.loggers.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.loggers.enabled=true # Enable the loggers endpoint.
endpoints.loggers.jmx.enabled=true # Expose the loggers endpoint as a JMX MBean.
endpoints.loggers.web.enabled=false # Expose the loggers endpoint as a Web endpoint.
endpoints.loggers.enabled= # Enable the loggers endpoint.
endpoints.loggers.jmx.enabled= # Expose the loggers endpoint as a JMX MBean.
endpoints.loggers.web.enabled= # Expose the loggers endpoint as a Web endpoint.
# REQUEST MAPPING ENDPOINT ({sc-spring-boot-actuator}/endpoint/RequestMappingEndpoint.{sc-ext}[RequestMappingEndpoint])
endpoints.mappings.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.mappings.enabled=true # Enable the mappings endpoint.
endpoints.mappings.jmx.enabled=true # Expose the mappings endpoint as a JMX MBean.
endpoints.mappings.web.enabled=false # Expose the mappings endpoint as a Web endpoint.
endpoints.mappings.enabled= # Enable the mappings endpoint.
endpoints.mappings.jmx.enabled= # Expose the mappings endpoint as a JMX MBean.
endpoints.mappings.web.enabled= # Expose the mappings endpoint as a Web endpoint.
# METRICS ENDPOINT ({sc-spring-boot-actuator}/endpoint/MetricsEndpoint.{sc-ext}[MetricsEndpoint])
endpoints.metrics.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.metrics.enabled=true # Enable the metrics endpoint.
endpoints.metrics.jmx.enabled=true # Expose the metrics endpoint as a JMX MBean.
endpoints.metrics.web.enabled=false # Expose the metrics endpoint as a Web endpoint.
endpoints.metrics.enabled= # Enable the metrics endpoint.
endpoints.metrics.jmx.enabled= # Expose the metrics endpoint as a JMX MBean.
endpoints.metrics.web.enabled= # Expose the metrics endpoint as a Web endpoint.
# SHUTDOWN ENDPOINT ({sc-spring-boot-actuator}/endpoint/ShutdownEndpoint.{sc-ext}[ShutdownEndpoint])
endpoints.shutdown.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
@ -1170,21 +1170,21 @@ content into your application; rather pick only the properties that you need.
# STATUS ENDPOINT ({sc-spring-boot-actuator}/endpoint/StatusEndpoint.{sc-ext}[StatusEndpoint])
endpoints.status.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.status.enabled=true # Enable the status endpoint.
endpoints.status.jmx.enabled=true # Expose the status endpoint as a JMX MBean.
endpoints.status.web.enabled=false # Expose the status endpoint as a Web endpoint.
endpoints.status.enabled= # Enable the status endpoint.
endpoints.status.jmx.enabled= # Expose the status endpoint as a JMX MBean.
endpoints.status.web.enabled= # Expose the status endpoint as a Web endpoint.
# THREAD DUMP ENDPOINT ({sc-spring-boot-actuator}/endpoint/ThreadDumpEndpoint.{sc-ext}[ThreadDumpEndpoint])
endpoints.threaddump.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.threaddump.enabled=true # Enable the threaddump endpoint.
endpoints.threaddump.jmx.enabled=true # Expose the threaddump endpoint as a JMX MBean.
endpoints.threaddump.web.enabled=false # Expose the threaddump endpoint as a Web endpoint.
endpoints.threaddump.enabled= # Enable the threaddump endpoint.
endpoints.threaddump.jmx.enabled= # Expose the threaddump endpoint as a JMX MBean.
endpoints.threaddump.web.enabled= # Expose the threaddump endpoint as a Web endpoint.
# TRACE ENDPOINT ({sc-spring-boot-actuator}/endpoint/TraceEndpoint.{sc-ext}[TraceEndpoint])
endpoints.trace.cache.time-to-live=0 # Maximum time in milliseconds that a response can be cached.
endpoints.trace.enabled=true # Enable the trace endpoint.
endpoints.trace.jmx.enabled=true # Expose the trace endpoint as a JMX MBean.
endpoints.trace.web.enabled=false # Expose the trace endpoint as a Web endpoint.
endpoints.trace.enabled= # Enable the trace endpoint.
endpoints.trace.jmx.enabled= # Expose the trace endpoint as a JMX MBean.
endpoints.trace.web.enabled= # Expose the trace endpoint as a Web endpoint.
# MANAGEMENT HTTP SERVER ({sc-spring-boot-actuator}/autoconfigure/web/ManagementServerProperties.{sc-ext}[ManagementServerProperties])
management.add-application-context-header=false # Add the "X-Application-Context" HTTP header in each response.

@ -367,10 +367,8 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
if (endpointId == null || "".equals(endpointId)) {
return; // Can't process that endpoint
}
Boolean enabledByDefault = (Boolean) elementValues.get("enabledByDefault");
if (enabledByDefault == null) {
enabledByDefault = Boolean.TRUE;
}
Boolean enabledByDefault = determineEnabledByDefault(elementValues.get(
"defaultEnablement"));
String type = this.typeUtils.getQualifiedName(element);
this.metadataCollector
.add(ItemMetadata.newGroup(endpointKey(endpointId), type, type, null));
@ -395,8 +393,21 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
endpointKey(endpointId + ".web"), "enabled", Boolean.class.getName(),
type, null, String.format("Expose the %s endpoint as a Web endpoint.",
endpointId),
false, null));
enabledByDefault, null));
}
}
private Boolean determineEnabledByDefault(Object defaultEnablement) {
if (defaultEnablement != null) {
String value = String.valueOf(defaultEnablement);
if ("ENABLED".equals(value)) {
return true;
}
if ("DISABLED".equals(value)) {
return false;
}
}
return null;
}
private String endpointKey(String suffix) {

@ -38,6 +38,7 @@ import org.springframework.boot.configurationprocessor.metadata.Metadata;
import org.springframework.boot.configurationprocessor.metadata.TestJsonConverter;
import org.springframework.boot.configurationsample.endpoint.CustomPropertiesEndpoint;
import org.springframework.boot.configurationsample.endpoint.DisabledEndpoint;
import org.springframework.boot.configurationsample.endpoint.EnabledEndpoint;
import org.springframework.boot.configurationsample.endpoint.OnlyJmxEndpoint;
import org.springframework.boot.configurationsample.endpoint.OnlyWebEndpoint;
import org.springframework.boot.configurationsample.endpoint.SimpleEndpoint;
@ -538,9 +539,9 @@ public class ConfigurationMetadataAnnotationProcessorTests {
ConfigurationMetadata metadata = compile(SimpleEndpoint.class);
assertThat(metadata).has(
Metadata.withGroup("endpoints.simple").fromSource(SimpleEndpoint.class));
assertThat(metadata).has(enabledFlag("simple", true));
assertThat(metadata).has(jmxEnabledFlag("simple", true));
assertThat(metadata).has(webEnabledFlag("simple", false));
assertThat(metadata).has(enabledFlag("simple", null));
assertThat(metadata).has(jmxEnabledFlag("simple", null));
assertThat(metadata).has(webEnabledFlag("simple", null));
assertThat(metadata).has(cacheTtl("simple"));
assertThat(metadata.getItems()).hasSize(5);
}
@ -557,6 +558,18 @@ public class ConfigurationMetadataAnnotationProcessorTests {
assertThat(metadata.getItems()).hasSize(5);
}
@Test
public void enabledEndpoint() throws IOException {
ConfigurationMetadata metadata = compile(EnabledEndpoint.class);
assertThat(metadata).has(Metadata.withGroup("endpoints.enabled")
.fromSource(EnabledEndpoint.class));
assertThat(metadata).has(enabledFlag("enabled", true));
assertThat(metadata).has(jmxEnabledFlag("enabled", true));
assertThat(metadata).has(webEnabledFlag("enabled", true));
assertThat(metadata).has(cacheTtl("enabled"));
assertThat(metadata.getItems()).hasSize(5);
}
@Test
public void customPropertiesEndpoint() throws IOException {
ConfigurationMetadata metadata = compile(CustomPropertiesEndpoint.class);
@ -564,9 +577,9 @@ public class ConfigurationMetadataAnnotationProcessorTests {
.fromSource(CustomPropertiesEndpoint.class));
assertThat(metadata).has(Metadata.withProperty("endpoints.customprops.name")
.ofType(String.class).withDefaultValue("test"));
assertThat(metadata).has(enabledFlag("customprops", true));
assertThat(metadata).has(jmxEnabledFlag("customprops", true));
assertThat(metadata).has(webEnabledFlag("customprops", false));
assertThat(metadata).has(enabledFlag("customprops", null));
assertThat(metadata).has(jmxEnabledFlag("customprops", null));
assertThat(metadata).has(webEnabledFlag("customprops", null));
assertThat(metadata).has(cacheTtl("customprops"));
assertThat(metadata.getItems()).hasSize(6);
}
@ -576,8 +589,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
ConfigurationMetadata metadata = compile(OnlyJmxEndpoint.class);
assertThat(metadata).has(
Metadata.withGroup("endpoints.jmx").fromSource(OnlyJmxEndpoint.class));
assertThat(metadata).has(enabledFlag("jmx", true));
assertThat(metadata).has(jmxEnabledFlag("jmx", true));
assertThat(metadata).has(enabledFlag("jmx", null));
assertThat(metadata).has(jmxEnabledFlag("jmx", null));
assertThat(metadata).has(cacheTtl("jmx"));
assertThat(metadata.getItems()).hasSize(4);
}
@ -587,8 +600,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
ConfigurationMetadata metadata = compile(OnlyWebEndpoint.class);
assertThat(metadata).has(
Metadata.withGroup("endpoints.web").fromSource(OnlyWebEndpoint.class));
assertThat(metadata).has(enabledFlag("web", true));
assertThat(metadata).has(webEnabledFlag("web", false));
assertThat(metadata).has(enabledFlag("web", null));
assertThat(metadata).has(webEnabledFlag("web", null));
assertThat(metadata).has(cacheTtl("web"));
assertThat(metadata.getItems()).hasSize(4);
}
@ -600,13 +613,14 @@ public class ConfigurationMetadataAnnotationProcessorTests {
ConfigurationMetadata metadata = project.fullBuild();
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
.fromSource(IncrementalEndpoint.class));
assertThat(metadata).has(enabledFlag("incremental", true));
assertThat(metadata).has(jmxEnabledFlag("incremental", true));
assertThat(metadata).has(webEnabledFlag("incremental", false));
assertThat(metadata).has(enabledFlag("incremental", null));
assertThat(metadata).has(jmxEnabledFlag("incremental", null));
assertThat(metadata).has(webEnabledFlag("incremental", null));
assertThat(metadata).has(cacheTtl("incremental"));
assertThat(metadata.getItems()).hasSize(5);
project.replaceText(IncrementalEndpoint.class, "id = \"incremental\"",
"id = \"incremental\", enabledByDefault = false");
"id = \"incremental\", defaultEnablement = org.springframework.boot."
+ "configurationsample.DefaultEnablement.DISABLED");
metadata = project.incrementalBuild(IncrementalEndpoint.class);
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
.fromSource(IncrementalEndpoint.class));
@ -624,9 +638,9 @@ public class ConfigurationMetadataAnnotationProcessorTests {
ConfigurationMetadata metadata = project.fullBuild();
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
.fromSource(IncrementalEndpoint.class));
assertThat(metadata).has(enabledFlag("incremental", true));
assertThat(metadata).has(jmxEnabledFlag("incremental", true));
assertThat(metadata).has(webEnabledFlag("incremental", false));
assertThat(metadata).has(enabledFlag("incremental", null));
assertThat(metadata).has(jmxEnabledFlag("incremental", null));
assertThat(metadata).has(webEnabledFlag("incremental", null));
assertThat(metadata).has(cacheTtl("incremental"));
assertThat(metadata.getItems()).hasSize(5);
project.replaceText(IncrementalEndpoint.class, "id = \"incremental\"",
@ -635,8 +649,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
metadata = project.incrementalBuild(IncrementalEndpoint.class);
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
.fromSource(IncrementalEndpoint.class));
assertThat(metadata).has(enabledFlag("incremental", true));
assertThat(metadata).has(webEnabledFlag("incremental", false));
assertThat(metadata).has(enabledFlag("incremental", null));
assertThat(metadata).has(webEnabledFlag("incremental", null));
assertThat(metadata).has(cacheTtl("incremental"));
assertThat(metadata.getItems()).hasSize(4);
}
@ -648,8 +662,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
ConfigurationMetadata metadata = project.fullBuild();
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
.fromSource(IncrementalJmxEndpoint.class));
assertThat(metadata).has(enabledFlag("incremental", true));
assertThat(metadata).has(jmxEnabledFlag("incremental", true));
assertThat(metadata).has(enabledFlag("incremental", null));
assertThat(metadata).has(jmxEnabledFlag("incremental", null));
assertThat(metadata).has(cacheTtl("incremental"));
assertThat(metadata.getItems()).hasSize(4);
project.replaceText(IncrementalJmxEndpoint.class,
@ -657,29 +671,29 @@ public class ConfigurationMetadataAnnotationProcessorTests {
metadata = project.incrementalBuild(IncrementalJmxEndpoint.class);
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
.fromSource(IncrementalJmxEndpoint.class));
assertThat(metadata).has(enabledFlag("incremental", true));
assertThat(metadata).has(jmxEnabledFlag("incremental", true));
assertThat(metadata).has(webEnabledFlag("incremental", false));
assertThat(metadata).has(enabledFlag("incremental", null));
assertThat(metadata).has(jmxEnabledFlag("incremental", null));
assertThat(metadata).has(webEnabledFlag("incremental", null));
assertThat(metadata).has(cacheTtl("incremental"));
assertThat(metadata.getItems()).hasSize(5);
}
private Metadata.MetadataItemCondition enabledFlag(String endpointId,
boolean defaultValue) {
Boolean defaultValue) {
return Metadata.withEnabledFlag("endpoints." + endpointId + ".enabled")
.withDefaultValue(defaultValue)
.withDescription(String.format("Enable the %s endpoint.", endpointId));
}
private Metadata.MetadataItemCondition jmxEnabledFlag(String endpointId,
boolean defaultValue) {
Boolean defaultValue) {
return Metadata.withEnabledFlag("endpoints." + endpointId + ".jmx.enabled")
.withDefaultValue(defaultValue).withDescription(String
.format("Expose the %s endpoint as a JMX MBean.", endpointId));
}
private Metadata.MetadataItemCondition webEnabledFlag(String endpointId,
boolean defaultValue) {
Boolean defaultValue) {
return Metadata.withEnabledFlag("endpoints." + endpointId + ".web.enabled")
.withDefaultValue(defaultValue).withDescription(String
.format("Expose the %s endpoint as a Web endpoint.", endpointId));

@ -0,0 +1,22 @@
/*
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.configurationsample;
public enum DefaultEnablement {
ENABLED, DISABLED, NEUTRAL
}

@ -35,7 +35,7 @@ public @interface Endpoint {
String id();
boolean enabledByDefault() default true;
DefaultEnablement defaultEnablement() default DefaultEnablement.NEUTRAL;
EndpointExposure[] exposure() default {};

@ -16,14 +16,15 @@
package org.springframework.boot.configurationsample.endpoint;
import org.springframework.boot.configurationsample.DefaultEnablement;
import org.springframework.boot.configurationsample.Endpoint;
/**
* An endpoint that is disabled by default.
* An endpoint that is disabled unless configured explicitly.
*
* @author Stephane Nicoll
*/
@Endpoint(id = "disabled", enabledByDefault = false)
@Endpoint(id = "disabled", defaultEnablement = DefaultEnablement.DISABLED)
public class DisabledEndpoint {
}

@ -0,0 +1,30 @@
/*
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.configurationsample.endpoint;
import org.springframework.boot.configurationsample.DefaultEnablement;
import org.springframework.boot.configurationsample.Endpoint;
/**
* An endpoint that is enabled unless configured explicitly..
*
* @author Stephane Nicoll
*/
@Endpoint(id = "enabled", defaultEnablement = DefaultEnablement.ENABLED)
public class EnabledEndpoint {
}
Loading…
Cancel
Save