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.Arrays;
import java.util.List; import java.util.List;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper; import org.springframework.boot.actuate.endpoint.OperationParameterMapper;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint; 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.cache.CachingConfigurationFactory;
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceOperationParameterMapper; import org.springframework.boot.actuate.endpoint.convert.ConversionServiceOperationParameterMapper;
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType; import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;

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

@ -20,9 +20,9 @@ import java.util.Collection;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.boot.actuate.endpoint.EndpointDiscoverer; 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.EndpointInfo;
import org.springframework.boot.actuate.endpoint.Operation; import org.springframework.boot.actuate.endpoint.Operation;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
/** /**
@ -61,7 +61,7 @@ public class EndpointProvider<T extends Operation> {
private boolean isEnabled(EndpointInfo<?> endpoint) { private boolean isEnabled(EndpointInfo<?> endpoint) {
return this.endpointEnablementProvider.getEndpointEnablement(endpoint.getId(), 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.RetentionPolicy;
import java.lang.annotation.Target; 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.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Conditional;
/** /**
* {@link Conditional} that checks whether an endpoint is enabled or not. Matches * {@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. * {@link Endpoint} may be restricted to.
* <p> * <p>
* If no specific {@code endpoints.<id>.*} or {@code endpoints.default.*} properties are * When an endpoint uses {@link DefaultEnablement#DISABLED}, it will only be enabled if
* defined, the condition matches the {@code enabledByDefault} value regardless of the * {@code endpoint.<name>.enabled}, {@code endpoint.<name>.jmx.enabled} or
* specific {@link EndpointExposure}, if any. If any property are set, they are evaluated * {@code endpoint.<name>.web.enabled} is {@code true}.
* with a sensible order of precedence.
* <p> * <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 * 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> * <p>
* This condition must be placed on a {@code @Bean} method producing an endpoint as its id * 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 * 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 { ... } * static class MyEndpoint { ... }
* *
* }</pre> * }</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.EndpointEnablement;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointEnablementProvider; 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.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxEndpointExtension; import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxEndpointExtension;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointExtension; import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointExtension;
import org.springframework.boot.autoconfigure.condition.ConditionMessage; 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 // If both types are set, all exposure technologies are exposed
EndpointExposure[] exposures = endpoint.exposure(); EndpointExposure[] exposures = endpoint.exposure();
return new EndpointAttributes(endpoint.id(), endpoint.enabledByDefault(), return new EndpointAttributes(endpoint.id(), endpoint.defaultEnablement(),
(exposures.length == 1 ? exposures[0] : null)); (exposures.length == 1 ? exposures[0] : null));
} }
@ -114,21 +115,23 @@ class OnEnabledEndpointCondition extends SpringBootCondition {
private final String id; private final String id;
private final boolean enabled; private final DefaultEnablement defaultEnablement;
private final EndpointExposure exposure; private final EndpointExposure exposure;
EndpointAttributes(String id, boolean enabled, EndpointExposure exposure) { EndpointAttributes(String id, DefaultEnablement defaultEnablement,
EndpointExposure exposure) {
if (!StringUtils.hasText(id)) { if (!StringUtils.hasText(id)) {
throw new IllegalStateException("Endpoint id could not be determined"); throw new IllegalStateException("Endpoint id could not be determined");
} }
this.id = id; this.id = id;
this.enabled = enabled; this.defaultEnablement = defaultEnablement;
this.exposure = exposure; this.exposure = exposure;
} }
public EndpointEnablement getEnablement(EndpointEnablementProvider provider) { 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.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.endpoint.DefaultCachingConfigurationFactory; import org.springframework.boot.actuate.autoconfigure.endpoint.DefaultCachingConfigurationFactory;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointProvider; 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.OperationParameterMapper;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint; 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.EndpointMBeanRegistrar;
import org.springframework.boot.actuate.endpoint.jmx.JmxEndpointOperation; import org.springframework.boot.actuate.endpoint.jmx.JmxEndpointOperation;
import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxAnnotationEndpointDiscoverer; import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxAnnotationEndpointDiscoverer;

@ -20,7 +20,8 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; 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.boot.test.util.TestPropertyValues;
import org.springframework.mock.env.MockEnvironment; import org.springframework.mock.env.MockEnvironment;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -38,306 +39,238 @@ public class EndpointEnablementProviderTests {
public ExpectedException thrown = ExpectedException.none(); public ExpectedException thrown = ExpectedException.none();
@Test @Test
public void cannotDetermineEnablementWithEmptyEndpoint() { public void defaultEnablementDisabled() {
this.thrown.expect(IllegalArgumentException.class); EndpointEnablement enablement = getEndpointEnablement("foo",
this.thrown.expectMessage("Endpoint id must have a value"); DefaultEnablement.DISABLED);
getEndpointEnablement(" ", true); validate(enablement, false, "endpoint 'foo' is disabled by default");
} }
@Test @Test
public void cannotDetermineEnablementOfEndpointAll() { public void defaultEnablementDisabledWithGeneralEnablement() {
this.thrown.expect(IllegalArgumentException.class); EndpointEnablement enablement = getEndpointEnablement("foo",
this.thrown.expectMessage("Endpoint id 'default' is a reserved value and cannot " DefaultEnablement.DISABLED, "endpoints.default.enabled=true");
+ "be used by an endpoint"); validate(enablement, false, "endpoint 'foo' is disabled by default");
getEndpointEnablement("default", true);
} }
@Test @Test
public void generalEnabledByDefault() { public void defaultEnablementDisabledWithGeneralTechEnablement() {
EndpointEnablement enablement = getEndpointEnablement("foo", true); EndpointEnablement enablement = getEndpointEnablement("foo",
validate(enablement, true, "endpoint 'foo' is enabled by default"); DefaultEnablement.DISABLED, EndpointExposure.WEB,
} "endpoints.default.web.enabled=true");
validate(enablement, false, "endpoint 'foo' (web) is disabled 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");
} }
@Test @Test
public void generalEnabledOverrideViaSpecificProperty() { public void defaultEnablementDisabledWithOverride() {
EndpointEnablement enablement = getEndpointEnablement("foo", true, EndpointEnablement enablement = getEndpointEnablement("foo",
"endpoints.default.enabled=false", "endpoints.foo.enabled=true"); DefaultEnablement.DISABLED, "endpoints.foo.enabled=true");
validate(enablement, true, "found property endpoints.foo.enabled"); validate(enablement, true, "found property endpoints.foo.enabled");
} }
@Test @Test
public void generalEnabledOverrideViaSpecificWebProperty() { public void defaultEnablementDisabledWithTechOverride() {
EndpointEnablement enablement = getEndpointEnablement("foo", true, EndpointEnablement enablement = getEndpointEnablement("foo",
"endpoints.foo.enabled=false", "endpoints.foo.web.enabled=true"); DefaultEnablement.DISABLED, EndpointExposure.WEB,
"endpoints.foo.web.enabled=true");
validate(enablement, true, "found property endpoints.foo.web.enabled"); validate(enablement, true, "found property endpoints.foo.web.enabled");
} }
@Test @Test
public void generalEnabledOverrideViaSpecificJmxProperty() { public void defaultEnablementDisabledWithIrrelevantTechOverride() {
EndpointEnablement enablement = getEndpointEnablement("foo", true, EndpointEnablement enablement = getEndpointEnablement("foo",
"endpoints.foo.enabled=false", "endpoints.foo.jmx.enabled=true"); DefaultEnablement.DISABLED, EndpointExposure.WEB,
validate(enablement, true, "found property endpoints.foo.jmx.enabled"); "endpoints.foo.jmx.enabled=true");
} validate(enablement, false, "endpoint 'foo' (web) is disabled by default");
@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");
} }
@Test @Test
public void generalEnabledOverrideWithAndAnnotationFlagAndSpecificProperty() { public void defaultEnablementEnabled() {
EndpointEnablement enablement = getEndpointEnablement("bar", false, EndpointEnablement enablement = getEndpointEnablement("bar",
"endpoints.bar.enabled=true"); DefaultEnablement.ENABLED);
validate(enablement, true, "found property endpoints.bar.enabled"); validate(enablement, true, "endpoint 'bar' is enabled by default");
} }
@Test @Test
public void generalEnabledOverrideWithAndAnnotationFlagAndSpecificWebProperty() { public void defaultEnablementEnabledWithGeneralDisablement() {
EndpointEnablement enablement = getEndpointEnablement("bar", false, EndpointEnablement enablement = getEndpointEnablement("bar",
"endpoints.bar.web.enabled=true"); DefaultEnablement.ENABLED, "endpoints.default.enabled=false");
validate(enablement, true, "found property endpoints.bar.web.enabled"); validate(enablement, true, "endpoint 'bar' is enabled by default");
} }
@Test @Test
public void generalEnabledOverrideWithAndAnnotationFlagAndSpecificJmxProperty() { public void defaultEnablementEnabledWithGeneralTechDisablement() {
EndpointEnablement enablement = getEndpointEnablement("bar", false, EndpointEnablement enablement = getEndpointEnablement("bar",
"endpoints.bar.jmx.enabled=true"); DefaultEnablement.ENABLED, EndpointExposure.JMX,
validate(enablement, true, "found property endpoints.bar.jmx.enabled"); "endpoints.default.jmx.enabled=false");
validate(enablement, true, "endpoint 'bar' (jmx) is enabled by default");
} }
@Test @Test
public void generalEnabledOverrideWithAndAnnotationFlagAndAnyProperty() { public void defaultEnablementEnabledWithOverride() {
EndpointEnablement enablement = getEndpointEnablement("bar", false, EndpointEnablement enablement = getEndpointEnablement("bar",
"endpoints.bar.web.enabled=false", "endpoints.bar.jmx.enabled=true"); DefaultEnablement.ENABLED, "endpoints.bar.enabled=false");
validate(enablement, true, "found property endpoints.bar.jmx.enabled"); validate(enablement, false, "found property endpoints.bar.enabled");
} }
@Test @Test
public void specificEnabledByDefault() { public void defaultEnablementEnabledWithTechOverride() {
EndpointEnablement enablement = getEndpointEnablement("foo", true, EndpointEnablement enablement = getEndpointEnablement("bar",
EndpointExposure.JMX); DefaultEnablement.ENABLED, EndpointExposure.JMX,
validate(enablement, true, "endpoint 'foo' (jmx) is enabled by default"); "endpoints.bar.jmx.enabled=false");
validate(enablement, false, "found property endpoints.bar.jmx.enabled");
} }
@Test @Test
public void specificDisabledViaEndpointProperty() { public void defaultEnablementEnabledWithIrrelevantTechOverride() {
EndpointEnablement enablement = getEndpointEnablement("foo", true, EndpointEnablement enablement = getEndpointEnablement("bar",
EndpointExposure.WEB, "endpoints.foo.enabled=false"); DefaultEnablement.ENABLED, EndpointExposure.JMX,
validate(enablement, false, "found property endpoints.foo.enabled"); "endpoints.bar.web.enabled=false");
validate(enablement, true, "endpoint 'bar' (jmx) is enabled by default");
} }
@Test @Test
public void specificDisabledViaTechProperty() { public void defaultEnablementNeutral() {
EndpointEnablement enablement = getEndpointEnablement("foo", true, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.WEB, "endpoints.foo.web.enabled=false"); DefaultEnablement.NEUTRAL);
validate(enablement, false, "found property endpoints.foo.web.enabled"); validate(enablement, true,
"endpoint 'biz' is enabled (default)");
} }
@Test @Test
public void specificNotDisabledViaUnrelatedTechProperty() { public void defaultEnablementNeutralWeb() {
EndpointEnablement enablement = getEndpointEnablement("foo", true, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.JMX, "endpoints.foo.web.enabled=false"); DefaultEnablement.NEUTRAL, EndpointExposure.WEB);
validate(enablement, true, "endpoint 'foo' (jmx) is enabled by default"); validate(enablement, false,
"endpoint 'default' (web) is disabled by default");
} }
@Test @Test
public void specificDisabledViaGeneralProperty() { public void defaultEnablementNeutralJmx() {
EndpointEnablement enablement = getEndpointEnablement("foo", true, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.JMX, "endpoints.default.enabled=false"); DefaultEnablement.NEUTRAL, EndpointExposure.JMX);
validate(enablement, false, "found property endpoints.default.enabled"); validate(enablement, true,
"endpoint 'biz' (jmx) is enabled (default for jmx endpoints)");
} }
@Test @Test
public void specificEnabledOverrideViaEndpointProperty() { public void defaultEnablementNeutralWithGeneralDisablement() {
EndpointEnablement enablement = getEndpointEnablement("foo", true, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.WEB, "endpoints.default.enabled=false", DefaultEnablement.NEUTRAL, "endpoints.default.enabled=false");
"endpoints.foo.enabled=true"); validate(enablement, false,
validate(enablement, true, "found property endpoints.foo.enabled"); "found property endpoints.default.enabled");
} }
@Test @Test
public void specificEnabledOverrideViaTechProperty() { public void defaultEnablementNeutralWebWithTechDisablement() {
EndpointEnablement enablement = getEndpointEnablement("foo", true, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.WEB, "endpoints.foo.enabled=false", DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.foo.web.enabled=true"); "endpoints.default.jmx.enabled=false");
validate(enablement, true, "found property endpoints.foo.web.enabled"); validate(enablement, false,
"found property endpoints.default.jmx.enabled");
} }
@Test @Test
public void specificEnabledOverrideHasNotEffectWithUnrelatedTechProperty() { public void defaultEnablementNeutralTechTakesPrecedence() {
EndpointEnablement enablement = getEndpointEnablement("foo", true, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.WEB, "endpoints.foo.enabled=false", DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.foo.jmx.enabled=true"); "endpoints.default.enabled=true",
validate(enablement, false, "found property endpoints.foo.enabled"); "endpoints.default.jmx.enabled=false");
validate(enablement, false,
"found property endpoints.default.jmx.enabled");
} }
@Test @Test
public void specificEnabledOverrideViaGeneralWebProperty() { public void defaultEnablementNeutralWebWithTechEnablement() {
EndpointEnablement enablement = getEndpointEnablement("foo", true, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.WEB, "endpoints.default.enabled=false", DefaultEnablement.NEUTRAL, EndpointExposure.WEB,
"endpoints.default.web.enabled=true"); "endpoints.default.web.enabled=true");
validate(enablement, true, "found property endpoints.default.web.enabled"); 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");
} }
@Test @Test
public void specificDisabledWithTechPropertyEvenWithEnabledGeneralProperties() { public void defaultEnablementNeutralWebWithUnrelatedTechDisablement() {
EndpointEnablement enablement = getEndpointEnablement("foo", true, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.WEB, "endpoints.default.enabled=true", DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
"endpoints.default.web.enabled=true", "endpoints.default.web.enabled=false");
"endpoints.default.jmx.enabled=true", "endpoints.foo.enabled=true", validate(enablement, true,
"endpoints.foo.web.enabled=false"); "endpoint 'biz' (jmx) is enabled (default for jmx endpoints)");
validate(enablement, false, "found property endpoints.foo.web.enabled");
} }
@Test @Test
public void specificDisabledByDefaultWithAnnotationFlag() { public void defaultEnablementNeutralWithOverride() {
EndpointEnablement enablement = getEndpointEnablement("bar", false, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.WEB); DefaultEnablement.NEUTRAL, "endpoints.biz.enabled=false");
validate(enablement, false, "endpoint 'bar' (web) is disabled by default"); validate(enablement, false,
"found property endpoints.biz.enabled");
} }
@Test @Test
public void specificDisabledByDefaultWithAnnotationFlagEvenWithGeneralProperty() { public void defaultEnablementNeutralWebWithOverride() {
EndpointEnablement enablement = getEndpointEnablement("bar", false, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.WEB, "endpoints.default.enabled=true"); DefaultEnablement.NEUTRAL, EndpointExposure.WEB,
validate(enablement, false, "endpoint 'bar' (web) is disabled by default"); "endpoints.biz.web.enabled=true");
validate(enablement, true,
"found property endpoints.biz.web.enabled");
} }
@Test @Test
public void specificDisabledByDefaultWithAnnotationFlagEvenWithGeneralWebProperty() { public void defaultEnablementNeutralJmxWithOverride() {
EndpointEnablement enablement = getEndpointEnablement("bar", false, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.WEB, "endpoints.default.web.enabled=true"); DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
validate(enablement, false, "endpoint 'bar' (web) is disabled by default"); "endpoints.biz.jmx.enabled=false");
validate(enablement, false,
"found property endpoints.biz.jmx.enabled");
} }
@Test @Test
public void specificDisabledByDefaultWithAnnotationFlagEvenWithGeneralJmxProperty() { public void defaultEnablementNeutralTechTakesPrecedenceOnEverything() {
EndpointEnablement enablement = getEndpointEnablement("bar", false, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.WEB, "endpoints.default.jmx.enabled=true"); DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
validate(enablement, false, "endpoint 'bar' (web) is disabled by default"); "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 @Test
public void specificEnabledOverrideWithAndAnnotationFlagAndEndpointProperty() { public void defaultEnablementNeutralSpecificTakesPrecedenceOnDefaults() {
EndpointEnablement enablement = getEndpointEnablement("bar", false, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.WEB, "endpoints.bar.enabled=true"); DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
validate(enablement, true, "found property endpoints.bar.enabled"); "endpoints.default.enabled=false",
"endpoints.default.jmx.enabled=false",
"endpoints.biz.enabled=true");
validate(enablement, true,
"found property endpoints.biz.enabled");
} }
@Test @Test
public void specificEnabledOverrideWithAndAnnotationFlagAndTechProperty() { public void defaultEnablementNeutralDefaultTechTakesPrecedenceOnGeneralDefault() {
EndpointEnablement enablement = getEndpointEnablement("bar", false, EndpointEnablement enablement = getEndpointEnablement("biz",
EndpointExposure.WEB, "endpoints.bar.web.enabled=true"); DefaultEnablement.NEUTRAL, EndpointExposure.JMX,
validate(enablement, true, "found property endpoints.bar.web.enabled"); "endpoints.default.enabled=false",
} "endpoints.default.jmx.enabled=true");
validate(enablement, true,
@Test "found property endpoints.default.jmx.enabled");
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");
} }
private EndpointEnablement getEndpointEnablement(String id, boolean enabledByDefault, private EndpointEnablement getEndpointEnablement(String id,
String... environment) { DefaultEnablement enabledByDefault, String... environment) {
return getEndpointEnablement(id, enabledByDefault, null, environment); return getEndpointEnablement(id, enabledByDefault, null, environment);
} }
private EndpointEnablement getEndpointEnablement(String id, boolean enabledByDefault, private EndpointEnablement getEndpointEnablement(String id,
EndpointExposure exposure, String... environment) { DefaultEnablement enabledByDefault, EndpointExposure exposure,
String... environment) {
MockEnvironment env = new MockEnvironment(); MockEnvironment env = new MockEnvironment();
TestPropertyValues.of(environment).applyTo(env); TestPropertyValues.of(environment).applyTo(env);
EndpointEnablementProvider provider = new EndpointEnablementProvider(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, 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.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.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxEndpointExtension; import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxEndpointExtension;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointExtension; import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointExtension;
import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@ -297,7 +298,7 @@ public class ConditionalOnEnabledEndpointTests {
} }
@Endpoint(id = "bar", exposure = { EndpointExposure.WEB, @Endpoint(id = "bar", exposure = { EndpointExposure.WEB,
EndpointExposure.JMX }, enabledByDefault = false) EndpointExposure.JMX }, defaultEnablement = DefaultEnablement.DISABLED)
static class BarEndpoint { 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.endpoint.EndpointProvider;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; 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.EndpointInfo;
import org.springframework.boot.actuate.endpoint.web.WebEndpointOperation; import org.springframework.boot.actuate.endpoint.web.WebEndpointOperation;
@ -82,8 +83,10 @@ public class DefaultEndpointPathProviderTests {
private DefaultEndpointPathProvider createProvider(String contextPath) { private DefaultEndpointPathProvider createProvider(String contextPath) {
Collection<EndpointInfo<WebEndpointOperation>> endpoints = new ArrayList<>(); Collection<EndpointInfo<WebEndpointOperation>> endpoints = new ArrayList<>();
endpoints.add(new EndpointInfo<>("foo", true, Collections.emptyList())); endpoints.add(new EndpointInfo<>("foo", DefaultEnablement.ENABLED,
endpoints.add(new EndpointInfo<>("bar", true, Collections.emptyList())); Collections.emptyList()));
endpoints.add(new EndpointInfo<>("bar", DefaultEnablement.ENABLED,
Collections.emptyList()));
given(this.endpointProvider.getEndpoints()).willReturn(endpoints); given(this.endpointProvider.getEndpoints()).willReturn(endpoints);
ManagementServerProperties managementServerProperties = new ManagementServerProperties(); ManagementServerProperties managementServerProperties = new ManagementServerProperties();
managementServerProperties.setContextPath(contextPath); managementServerProperties.setContextPath(contextPath);

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

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

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

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

@ -22,14 +22,15 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; 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. * Identifies a type as being an endpoint.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
* @since 2.0.0 * @since 2.0.0
* @see EndpointDiscoverer * @see AnnotationEndpointDiscoverer
*/ */
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@ -50,9 +51,10 @@ public @interface Endpoint {
EndpointExposure[] exposure() default {}; EndpointExposure[] exposure() default {};
/** /**
* Whether or not the endpoint is enabled by default. * Defines the {@link DefaultEnablement} of the endpoint. By default, the endpoint's
* @return {@code true} if the endpoint is enabled by default, otherwise {@code false} * 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.function.Supplier;
import java.util.stream.Collectors; 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.EndpointInfo;
import org.springframework.boot.actuate.endpoint.OperationInvoker; import org.springframework.boot.actuate.endpoint.OperationInvoker;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper; 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.ReflectiveOperationInvoker;
import org.springframework.boot.actuate.endpoint.annotation.AnnotationEndpointDiscoverer; import org.springframework.boot.actuate.endpoint.annotation.AnnotationEndpointDiscoverer;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint; 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.CachingConfiguration;
import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory; import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory;
import org.springframework.boot.actuate.endpoint.cache.CachingOperationInvoker; import org.springframework.boot.actuate.endpoint.cache.CachingOperationInvoker;

@ -27,6 +27,7 @@ import java.util.stream.Stream;
import org.reactivestreams.Publisher; import org.reactivestreams.Publisher;
import org.springframework.boot.actuate.endpoint.EndpointExposure;
import org.springframework.boot.actuate.endpoint.EndpointInfo; import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.OperationInvoker; import org.springframework.boot.actuate.endpoint.OperationInvoker;
import org.springframework.boot.actuate.endpoint.OperationParameterMapper; 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.ReflectiveOperationInvoker;
import org.springframework.boot.actuate.endpoint.annotation.AnnotationEndpointDiscoverer; import org.springframework.boot.actuate.endpoint.annotation.AnnotationEndpointDiscoverer;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint; 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.annotation.Selector;
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration; import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration;
import org.springframework.boot.actuate.endpoint.cache.CachingConfigurationFactory; 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.Log;
import org.apache.commons.logging.LogFactory; 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.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.logging.LogFile; 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.Log;
import org.apache.commons.logging.LogFactory; 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.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.EndpointExposure;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;

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

@ -26,11 +26,11 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; 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.EndpointInfo;
import org.springframework.boot.actuate.endpoint.ReflectiveOperationInvoker; import org.springframework.boot.actuate.endpoint.ReflectiveOperationInvoker;
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation; import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint; 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.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration; import org.springframework.boot.actuate.endpoint.cache.CachingConfiguration;

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

@ -32,11 +32,11 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; 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.EndpointInfo;
import org.springframework.boot.actuate.endpoint.OperationInvoker; import org.springframework.boot.actuate.endpoint.OperationInvoker;
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation; import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint; 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.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector; import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; 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]) # 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.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.enabled= # Enable the auditevents endpoint.
endpoints.auditevents.jmx.enabled=true # Expose the auditevents endpoint as a JMX MBean. endpoints.auditevents.jmx.enabled= # Expose the auditevents endpoint as a JMX MBean.
endpoints.auditevents.web.enabled=false # Expose the auditevents endpoint as a Web endpoint. 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]) # 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.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.enabled= # Enable the autoconfig endpoint.
endpoints.autoconfig.jmx.enabled=true # Expose the autoconfig endpoint as a JMX MBean. endpoints.autoconfig.jmx.enabled= # Expose the autoconfig endpoint as a JMX MBean.
endpoints.autoconfig.web.enabled=false # Expose the autoconfig endpoint as a Web endpoint. endpoints.autoconfig.web.enabled= # Expose the autoconfig endpoint as a Web endpoint.
# BEANS ENDPOINT ({sc-spring-boot-actuator}/endpoint/BeansEndpoint.{sc-ext}[BeansEndpoint]) # 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.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.enabled= # Enable the beans endpoint.
endpoints.beans.jmx.enabled=true # Expose the beans endpoint as a JMX MBean. endpoints.beans.jmx.enabled= # Expose the beans endpoint as a JMX MBean.
endpoints.beans.web.enabled=false # Expose the beans endpoint as a Web endpoint. 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]) # 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.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.enabled= # Enable the configprops endpoint.
endpoints.configprops.jmx.enabled=true # Expose the configprops endpoint as a JMX MBean. 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.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 # ENDPOINT DEFAULT SETTINGS
endpoints.default.enabled=true # Enable all endpoints by default. 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]) # 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.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.enabled= # Enable the env endpoint.
endpoints.env.jmx.enabled=true # Expose the env endpoint as a JMX MBean. 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.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]) # 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.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.enabled= # Enable the flyway endpoint.
endpoints.flyway.jmx.enabled=true # Expose the flyway endpoint as a JMX MBean. endpoints.flyway.jmx.enabled= # Expose the flyway endpoint as a JMX MBean.
endpoints.flyway.web.enabled=false # Expose the flyway endpoint as a Web endpoint. endpoints.flyway.web.enabled= # Expose the flyway endpoint as a Web endpoint.
# HEALTH ENDPOINT ({sc-spring-boot-actuator}/endpoint/HealthEndpoint.{sc-ext}[HealthEndpoint]) # 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.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.enabled= # Enable the health endpoint.
endpoints.health.jmx.enabled=true # Expose the health endpoint as a JMX MBean. endpoints.health.jmx.enabled= # Expose the health endpoint as a JMX MBean.
endpoints.health.web.enabled=false # Expose the health endpoint as a Web endpoint. 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]) # 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.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.enabled= # Enable the heapdump endpoint.
endpoints.heapdump.web.enabled=false # Expose the heapdump endpoint as a Web endpoint. endpoints.heapdump.web.enabled= # Expose the heapdump endpoint as a Web endpoint.
# INFO ENDPOINT ({sc-spring-boot-actuator}/endpoint/InfoEndpoint.{sc-ext}[InfoEndpoint]) # 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.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.enabled= # Enable the info endpoint.
endpoints.info.jmx.enabled=true # Expose the info endpoint as a JMX MBean. endpoints.info.jmx.enabled= # Expose the info endpoint as a JMX MBean.
endpoints.info.web.enabled=false # Expose the info endpoint as a Web endpoint. endpoints.info.web.enabled= # Expose the info endpoint as a Web endpoint.
# LIQUIBASE ENDPOINT ({sc-spring-boot-actuator}/endpoint/LiquibaseEndpoint.{sc-ext}[LiquibaseEndpoint]) # 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.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.enabled= # Enable the liquibase endpoint.
endpoints.liquibase.jmx.enabled=true # Expose the liquibase endpoint as a JMX MBean. endpoints.liquibase.jmx.enabled= # Expose the liquibase endpoint as a JMX MBean.
endpoints.liquibase.web.enabled=false # Expose the liquibase endpoint as a Web endpoint. 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]) # 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.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.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]) # 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.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.enabled= # Enable the loggers endpoint.
endpoints.loggers.jmx.enabled=true # Expose the loggers endpoint as a JMX MBean. endpoints.loggers.jmx.enabled= # Expose the loggers endpoint as a JMX MBean.
endpoints.loggers.web.enabled=false # Expose the loggers endpoint as a Web endpoint. endpoints.loggers.web.enabled= # Expose the loggers endpoint as a Web endpoint.
# REQUEST MAPPING ENDPOINT ({sc-spring-boot-actuator}/endpoint/RequestMappingEndpoint.{sc-ext}[RequestMappingEndpoint]) # 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.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.enabled= # Enable the mappings endpoint.
endpoints.mappings.jmx.enabled=true # Expose the mappings endpoint as a JMX MBean. endpoints.mappings.jmx.enabled= # Expose the mappings endpoint as a JMX MBean.
endpoints.mappings.web.enabled=false # Expose the mappings endpoint as a Web endpoint. endpoints.mappings.web.enabled= # Expose the mappings endpoint as a Web endpoint.
# METRICS ENDPOINT ({sc-spring-boot-actuator}/endpoint/MetricsEndpoint.{sc-ext}[MetricsEndpoint]) # 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.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.enabled= # Enable the metrics endpoint.
endpoints.metrics.jmx.enabled=true # Expose the metrics endpoint as a JMX MBean. endpoints.metrics.jmx.enabled= # Expose the metrics endpoint as a JMX MBean.
endpoints.metrics.web.enabled=false # Expose the metrics endpoint as a Web endpoint. endpoints.metrics.web.enabled= # Expose the metrics endpoint as a Web endpoint.
# SHUTDOWN ENDPOINT ({sc-spring-boot-actuator}/endpoint/ShutdownEndpoint.{sc-ext}[ShutdownEndpoint]) # 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. 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]) # 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.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.enabled= # Enable the status endpoint.
endpoints.status.jmx.enabled=true # Expose the status endpoint as a JMX MBean. endpoints.status.jmx.enabled= # Expose the status endpoint as a JMX MBean.
endpoints.status.web.enabled=false # Expose the status endpoint as a Web endpoint. endpoints.status.web.enabled= # Expose the status endpoint as a Web endpoint.
# THREAD DUMP ENDPOINT ({sc-spring-boot-actuator}/endpoint/ThreadDumpEndpoint.{sc-ext}[ThreadDumpEndpoint]) # 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.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.enabled= # Enable the threaddump endpoint.
endpoints.threaddump.jmx.enabled=true # Expose the threaddump endpoint as a JMX MBean. endpoints.threaddump.jmx.enabled= # Expose the threaddump endpoint as a JMX MBean.
endpoints.threaddump.web.enabled=false # Expose the threaddump endpoint as a Web endpoint. endpoints.threaddump.web.enabled= # Expose the threaddump endpoint as a Web endpoint.
# TRACE ENDPOINT ({sc-spring-boot-actuator}/endpoint/TraceEndpoint.{sc-ext}[TraceEndpoint]) # 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.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.enabled= # Enable the trace endpoint.
endpoints.trace.jmx.enabled=true # Expose the trace endpoint as a JMX MBean. endpoints.trace.jmx.enabled= # Expose the trace endpoint as a JMX MBean.
endpoints.trace.web.enabled=false # Expose the trace endpoint as a Web endpoint. 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 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. 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)) { if (endpointId == null || "".equals(endpointId)) {
return; // Can't process that endpoint return; // Can't process that endpoint
} }
Boolean enabledByDefault = (Boolean) elementValues.get("enabledByDefault"); Boolean enabledByDefault = determineEnabledByDefault(elementValues.get(
if (enabledByDefault == null) { "defaultEnablement"));
enabledByDefault = Boolean.TRUE;
}
String type = this.typeUtils.getQualifiedName(element); String type = this.typeUtils.getQualifiedName(element);
this.metadataCollector this.metadataCollector
.add(ItemMetadata.newGroup(endpointKey(endpointId), type, type, null)); .add(ItemMetadata.newGroup(endpointKey(endpointId), type, type, null));
@ -395,8 +393,21 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
endpointKey(endpointId + ".web"), "enabled", Boolean.class.getName(), endpointKey(endpointId + ".web"), "enabled", Boolean.class.getName(),
type, null, String.format("Expose the %s endpoint as a Web endpoint.", type, null, String.format("Expose the %s endpoint as a Web endpoint.",
endpointId), 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) { 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.configurationprocessor.metadata.TestJsonConverter;
import org.springframework.boot.configurationsample.endpoint.CustomPropertiesEndpoint; import org.springframework.boot.configurationsample.endpoint.CustomPropertiesEndpoint;
import org.springframework.boot.configurationsample.endpoint.DisabledEndpoint; 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.OnlyJmxEndpoint;
import org.springframework.boot.configurationsample.endpoint.OnlyWebEndpoint; import org.springframework.boot.configurationsample.endpoint.OnlyWebEndpoint;
import org.springframework.boot.configurationsample.endpoint.SimpleEndpoint; import org.springframework.boot.configurationsample.endpoint.SimpleEndpoint;
@ -538,9 +539,9 @@ public class ConfigurationMetadataAnnotationProcessorTests {
ConfigurationMetadata metadata = compile(SimpleEndpoint.class); ConfigurationMetadata metadata = compile(SimpleEndpoint.class);
assertThat(metadata).has( assertThat(metadata).has(
Metadata.withGroup("endpoints.simple").fromSource(SimpleEndpoint.class)); Metadata.withGroup("endpoints.simple").fromSource(SimpleEndpoint.class));
assertThat(metadata).has(enabledFlag("simple", true)); assertThat(metadata).has(enabledFlag("simple", null));
assertThat(metadata).has(jmxEnabledFlag("simple", true)); assertThat(metadata).has(jmxEnabledFlag("simple", null));
assertThat(metadata).has(webEnabledFlag("simple", false)); assertThat(metadata).has(webEnabledFlag("simple", null));
assertThat(metadata).has(cacheTtl("simple")); assertThat(metadata).has(cacheTtl("simple"));
assertThat(metadata.getItems()).hasSize(5); assertThat(metadata.getItems()).hasSize(5);
} }
@ -557,6 +558,18 @@ public class ConfigurationMetadataAnnotationProcessorTests {
assertThat(metadata.getItems()).hasSize(5); 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 @Test
public void customPropertiesEndpoint() throws IOException { public void customPropertiesEndpoint() throws IOException {
ConfigurationMetadata metadata = compile(CustomPropertiesEndpoint.class); ConfigurationMetadata metadata = compile(CustomPropertiesEndpoint.class);
@ -564,9 +577,9 @@ public class ConfigurationMetadataAnnotationProcessorTests {
.fromSource(CustomPropertiesEndpoint.class)); .fromSource(CustomPropertiesEndpoint.class));
assertThat(metadata).has(Metadata.withProperty("endpoints.customprops.name") assertThat(metadata).has(Metadata.withProperty("endpoints.customprops.name")
.ofType(String.class).withDefaultValue("test")); .ofType(String.class).withDefaultValue("test"));
assertThat(metadata).has(enabledFlag("customprops", true)); assertThat(metadata).has(enabledFlag("customprops", null));
assertThat(metadata).has(jmxEnabledFlag("customprops", true)); assertThat(metadata).has(jmxEnabledFlag("customprops", null));
assertThat(metadata).has(webEnabledFlag("customprops", false)); assertThat(metadata).has(webEnabledFlag("customprops", null));
assertThat(metadata).has(cacheTtl("customprops")); assertThat(metadata).has(cacheTtl("customprops"));
assertThat(metadata.getItems()).hasSize(6); assertThat(metadata.getItems()).hasSize(6);
} }
@ -576,8 +589,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
ConfigurationMetadata metadata = compile(OnlyJmxEndpoint.class); ConfigurationMetadata metadata = compile(OnlyJmxEndpoint.class);
assertThat(metadata).has( assertThat(metadata).has(
Metadata.withGroup("endpoints.jmx").fromSource(OnlyJmxEndpoint.class)); Metadata.withGroup("endpoints.jmx").fromSource(OnlyJmxEndpoint.class));
assertThat(metadata).has(enabledFlag("jmx", true)); assertThat(metadata).has(enabledFlag("jmx", null));
assertThat(metadata).has(jmxEnabledFlag("jmx", true)); assertThat(metadata).has(jmxEnabledFlag("jmx", null));
assertThat(metadata).has(cacheTtl("jmx")); assertThat(metadata).has(cacheTtl("jmx"));
assertThat(metadata.getItems()).hasSize(4); assertThat(metadata.getItems()).hasSize(4);
} }
@ -587,8 +600,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
ConfigurationMetadata metadata = compile(OnlyWebEndpoint.class); ConfigurationMetadata metadata = compile(OnlyWebEndpoint.class);
assertThat(metadata).has( assertThat(metadata).has(
Metadata.withGroup("endpoints.web").fromSource(OnlyWebEndpoint.class)); Metadata.withGroup("endpoints.web").fromSource(OnlyWebEndpoint.class));
assertThat(metadata).has(enabledFlag("web", true)); assertThat(metadata).has(enabledFlag("web", null));
assertThat(metadata).has(webEnabledFlag("web", false)); assertThat(metadata).has(webEnabledFlag("web", null));
assertThat(metadata).has(cacheTtl("web")); assertThat(metadata).has(cacheTtl("web"));
assertThat(metadata.getItems()).hasSize(4); assertThat(metadata.getItems()).hasSize(4);
} }
@ -600,13 +613,14 @@ public class ConfigurationMetadataAnnotationProcessorTests {
ConfigurationMetadata metadata = project.fullBuild(); ConfigurationMetadata metadata = project.fullBuild();
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental") assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
.fromSource(IncrementalEndpoint.class)); .fromSource(IncrementalEndpoint.class));
assertThat(metadata).has(enabledFlag("incremental", true)); assertThat(metadata).has(enabledFlag("incremental", null));
assertThat(metadata).has(jmxEnabledFlag("incremental", true)); assertThat(metadata).has(jmxEnabledFlag("incremental", null));
assertThat(metadata).has(webEnabledFlag("incremental", false)); assertThat(metadata).has(webEnabledFlag("incremental", null));
assertThat(metadata).has(cacheTtl("incremental")); assertThat(metadata).has(cacheTtl("incremental"));
assertThat(metadata.getItems()).hasSize(5); assertThat(metadata.getItems()).hasSize(5);
project.replaceText(IncrementalEndpoint.class, "id = \"incremental\"", project.replaceText(IncrementalEndpoint.class, "id = \"incremental\"",
"id = \"incremental\", enabledByDefault = false"); "id = \"incremental\", defaultEnablement = org.springframework.boot."
+ "configurationsample.DefaultEnablement.DISABLED");
metadata = project.incrementalBuild(IncrementalEndpoint.class); metadata = project.incrementalBuild(IncrementalEndpoint.class);
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental") assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
.fromSource(IncrementalEndpoint.class)); .fromSource(IncrementalEndpoint.class));
@ -624,9 +638,9 @@ public class ConfigurationMetadataAnnotationProcessorTests {
ConfigurationMetadata metadata = project.fullBuild(); ConfigurationMetadata metadata = project.fullBuild();
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental") assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
.fromSource(IncrementalEndpoint.class)); .fromSource(IncrementalEndpoint.class));
assertThat(metadata).has(enabledFlag("incremental", true)); assertThat(metadata).has(enabledFlag("incremental", null));
assertThat(metadata).has(jmxEnabledFlag("incremental", true)); assertThat(metadata).has(jmxEnabledFlag("incremental", null));
assertThat(metadata).has(webEnabledFlag("incremental", false)); assertThat(metadata).has(webEnabledFlag("incremental", null));
assertThat(metadata).has(cacheTtl("incremental")); assertThat(metadata).has(cacheTtl("incremental"));
assertThat(metadata.getItems()).hasSize(5); assertThat(metadata.getItems()).hasSize(5);
project.replaceText(IncrementalEndpoint.class, "id = \"incremental\"", project.replaceText(IncrementalEndpoint.class, "id = \"incremental\"",
@ -635,8 +649,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
metadata = project.incrementalBuild(IncrementalEndpoint.class); metadata = project.incrementalBuild(IncrementalEndpoint.class);
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental") assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
.fromSource(IncrementalEndpoint.class)); .fromSource(IncrementalEndpoint.class));
assertThat(metadata).has(enabledFlag("incremental", true)); assertThat(metadata).has(enabledFlag("incremental", null));
assertThat(metadata).has(webEnabledFlag("incremental", false)); assertThat(metadata).has(webEnabledFlag("incremental", null));
assertThat(metadata).has(cacheTtl("incremental")); assertThat(metadata).has(cacheTtl("incremental"));
assertThat(metadata.getItems()).hasSize(4); assertThat(metadata.getItems()).hasSize(4);
} }
@ -648,8 +662,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
ConfigurationMetadata metadata = project.fullBuild(); ConfigurationMetadata metadata = project.fullBuild();
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental") assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
.fromSource(IncrementalJmxEndpoint.class)); .fromSource(IncrementalJmxEndpoint.class));
assertThat(metadata).has(enabledFlag("incremental", true)); assertThat(metadata).has(enabledFlag("incremental", null));
assertThat(metadata).has(jmxEnabledFlag("incremental", true)); assertThat(metadata).has(jmxEnabledFlag("incremental", null));
assertThat(metadata).has(cacheTtl("incremental")); assertThat(metadata).has(cacheTtl("incremental"));
assertThat(metadata.getItems()).hasSize(4); assertThat(metadata.getItems()).hasSize(4);
project.replaceText(IncrementalJmxEndpoint.class, project.replaceText(IncrementalJmxEndpoint.class,
@ -657,29 +671,29 @@ public class ConfigurationMetadataAnnotationProcessorTests {
metadata = project.incrementalBuild(IncrementalJmxEndpoint.class); metadata = project.incrementalBuild(IncrementalJmxEndpoint.class);
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental") assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
.fromSource(IncrementalJmxEndpoint.class)); .fromSource(IncrementalJmxEndpoint.class));
assertThat(metadata).has(enabledFlag("incremental", true)); assertThat(metadata).has(enabledFlag("incremental", null));
assertThat(metadata).has(jmxEnabledFlag("incremental", true)); assertThat(metadata).has(jmxEnabledFlag("incremental", null));
assertThat(metadata).has(webEnabledFlag("incremental", false)); assertThat(metadata).has(webEnabledFlag("incremental", null));
assertThat(metadata).has(cacheTtl("incremental")); assertThat(metadata).has(cacheTtl("incremental"));
assertThat(metadata.getItems()).hasSize(5); assertThat(metadata.getItems()).hasSize(5);
} }
private Metadata.MetadataItemCondition enabledFlag(String endpointId, private Metadata.MetadataItemCondition enabledFlag(String endpointId,
boolean defaultValue) { Boolean defaultValue) {
return Metadata.withEnabledFlag("endpoints." + endpointId + ".enabled") return Metadata.withEnabledFlag("endpoints." + endpointId + ".enabled")
.withDefaultValue(defaultValue) .withDefaultValue(defaultValue)
.withDescription(String.format("Enable the %s endpoint.", endpointId)); .withDescription(String.format("Enable the %s endpoint.", endpointId));
} }
private Metadata.MetadataItemCondition jmxEnabledFlag(String endpointId, private Metadata.MetadataItemCondition jmxEnabledFlag(String endpointId,
boolean defaultValue) { Boolean defaultValue) {
return Metadata.withEnabledFlag("endpoints." + endpointId + ".jmx.enabled") return Metadata.withEnabledFlag("endpoints." + endpointId + ".jmx.enabled")
.withDefaultValue(defaultValue).withDescription(String .withDefaultValue(defaultValue).withDescription(String
.format("Expose the %s endpoint as a JMX MBean.", endpointId)); .format("Expose the %s endpoint as a JMX MBean.", endpointId));
} }
private Metadata.MetadataItemCondition webEnabledFlag(String endpointId, private Metadata.MetadataItemCondition webEnabledFlag(String endpointId,
boolean defaultValue) { Boolean defaultValue) {
return Metadata.withEnabledFlag("endpoints." + endpointId + ".web.enabled") return Metadata.withEnabledFlag("endpoints." + endpointId + ".web.enabled")
.withDefaultValue(defaultValue).withDescription(String .withDefaultValue(defaultValue).withDescription(String
.format("Expose the %s endpoint as a Web endpoint.", endpointId)); .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(); String id();
boolean enabledByDefault() default true; DefaultEnablement defaultEnablement() default DefaultEnablement.NEUTRAL;
EndpointExposure[] exposure() default {}; EndpointExposure[] exposure() default {};

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