Separate endpoint concerns
Update endpoint code to provide cleaner separation of concerns. Specifically, the top level endpoint package is no longer aware of the fact that JMX and HTTP are ultimately used to expose endpoints. Caching concerns have also been abstracted behind a general purpose `OperationMethodInvokerAdvisor` interface. Configuration properties have been refined to further enforce separation. The `management.endpoint.<name>` prefix provides configuration for a single endpoint (including enable and cache time-to-live). These properties are now technology agnostic (they don't include `web` or `jmx` sub properties). The `management.endpoints.<technology>` prefix provide exposure specific configuration. For example, `management.endpoints.web.path-mapping` allow endpoint URLs to be changed. Endpoint enabled/disabled logic has been simplified so that endpoints can't be disabled per exposure technology. Instead a filter based approach is used to allow refinement of what endpoints are exposed over a given technology. Fixes gh-10176
This commit is contained in:
@@ -23,10 +23,10 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
@@ -42,6 +42,7 @@ import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.Elements;
|
||||
@@ -157,9 +158,8 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
|
||||
}
|
||||
TypeElement endpointType = elementUtils.getTypeElement(endpointAnnotation());
|
||||
if (endpointType != null) { // Is @Endpoint available
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(endpointType)) {
|
||||
processEndpoint(element);
|
||||
}
|
||||
getElementsAnnotatedOrMetaAnnotatedWith(roundEnv, endpointType)
|
||||
.forEach(this::processEndpoint);
|
||||
}
|
||||
if (roundEnv.processingOver()) {
|
||||
try {
|
||||
@@ -172,6 +172,41 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
|
||||
return false;
|
||||
}
|
||||
|
||||
private Map<Element, List<Element>> getElementsAnnotatedOrMetaAnnotatedWith(
|
||||
RoundEnvironment roundEnv, TypeElement annotation) {
|
||||
DeclaredType annotationType = (DeclaredType) annotation.asType();
|
||||
Map<Element, List<Element>> result = new LinkedHashMap<>();
|
||||
for (Element element : roundEnv.getRootElements()) {
|
||||
LinkedList<Element> stack = new LinkedList<>();
|
||||
stack.push(element);
|
||||
collectElementsAnnotatedOrMetaAnnotatedWith(annotationType, stack);
|
||||
stack.removeFirst();
|
||||
if (!stack.isEmpty()) {
|
||||
result.put(element, Collections.unmodifiableList(stack));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean collectElementsAnnotatedOrMetaAnnotatedWith(
|
||||
DeclaredType annotationType, LinkedList<Element> stack) {
|
||||
Element element = stack.peekLast();
|
||||
for (AnnotationMirror annotation : this.processingEnv.getElementUtils()
|
||||
.getAllAnnotationMirrors(element)) {
|
||||
Element annotationElement = annotation.getAnnotationType().asElement();
|
||||
if (!stack.contains(annotationElement)) {
|
||||
stack.addLast(annotationElement);
|
||||
if (annotationElement.equals(annotationType.asElement())) {
|
||||
return true;
|
||||
}
|
||||
if (!collectElementsAnnotatedOrMetaAnnotatedWith(annotationType, stack)) {
|
||||
stack.removeLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void processElement(Element element) {
|
||||
try {
|
||||
AnnotationMirror annotation = getAnnotation(element,
|
||||
@@ -360,9 +395,10 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
|
||||
}
|
||||
}
|
||||
|
||||
private void processEndpoint(Element element) {
|
||||
private void processEndpoint(Element element, List<Element> annotations) {
|
||||
try {
|
||||
AnnotationMirror annotation = getAnnotation(element, endpointAnnotation());
|
||||
String annotationName = this.typeUtils.getQualifiedName(annotations.get(0));
|
||||
AnnotationMirror annotation = getAnnotation(element, annotationName);
|
||||
if (element instanceof TypeElement) {
|
||||
processEndpoint(annotation, (TypeElement) element);
|
||||
}
|
||||
@@ -379,51 +415,17 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
|
||||
if (endpointId == null || "".equals(endpointId)) {
|
||||
return; // Can't process that endpoint
|
||||
}
|
||||
Boolean enabledByDefault = determineEnabledByDefault(
|
||||
elementValues.get("defaultEnablement"));
|
||||
Boolean enabledByDefault = (Boolean) elementValues.get("enableByDefault");
|
||||
String type = this.typeUtils.getQualifiedName(element);
|
||||
this.metadataCollector
|
||||
.add(ItemMetadata.newGroup(endpointKey(endpointId), type, type, null));
|
||||
this.metadataCollector.add(ItemMetadata.newProperty(endpointKey(endpointId),
|
||||
"enabled", Boolean.class.getName(), type, null,
|
||||
String.format("Enable the %s endpoint.", endpointId), enabledByDefault,
|
||||
null));
|
||||
String.format("Enable the %s endpoint.", endpointId),
|
||||
(enabledByDefault == null ? true : enabledByDefault), null));
|
||||
this.metadataCollector.add(ItemMetadata.newProperty(endpointKey(endpointId),
|
||||
"cache.time-to-live", Long.class.getName(), type, null,
|
||||
"Maximum time in milliseconds that a response can be cached.", 0, null));
|
||||
EndpointExposure endpointTypes = EndpointExposure
|
||||
.parse(elementValues.get("exposure"));
|
||||
if (endpointTypes.hasJmx()) {
|
||||
this.metadataCollector.add(ItemMetadata.newProperty(
|
||||
endpointKey(endpointId + ".jmx"), "enabled", Boolean.class.getName(),
|
||||
type, null,
|
||||
String.format("Expose the %s endpoint as a JMX MBean.", endpointId),
|
||||
enabledByDefault, null));
|
||||
}
|
||||
if (endpointTypes.hasWeb()) {
|
||||
this.metadataCollector.add(ItemMetadata.newProperty(
|
||||
endpointKey(endpointId + ".web"), "enabled", Boolean.class.getName(),
|
||||
type, null, String.format("Expose the %s endpoint as a Web endpoint.",
|
||||
endpointId),
|
||||
enabledByDefault, null));
|
||||
this.metadataCollector.add(ItemMetadata.newProperty(endpointKey(endpointId),
|
||||
"web.path", String.class.getName(), type, null,
|
||||
String.format("Path of the %s endpoint.", endpointId), endpointId,
|
||||
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) {
|
||||
@@ -550,46 +552,4 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
|
||||
this.processingEnv.getMessager().printMessage(kind, msg);
|
||||
}
|
||||
|
||||
private static class EndpointExposure {
|
||||
|
||||
private static final List<String> ALL = Arrays.asList("JMX", "WEB");
|
||||
|
||||
private final List<String> types;
|
||||
|
||||
EndpointExposure(List<String> types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
static EndpointExposure parse(Object exposureAttribute) {
|
||||
List<AnnotationValue> values = asAnnotationValues(exposureAttribute);
|
||||
if (values.isEmpty()) {
|
||||
return new EndpointExposure(ALL);
|
||||
}
|
||||
return new EndpointExposure(
|
||||
values.stream().map(EndpointExposure::getValueAttribute)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static List<AnnotationValue> asAnnotationValues(Object typesAttribute) {
|
||||
if (!(typesAttribute instanceof List)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return (List<AnnotationValue>) typesAttribute;
|
||||
}
|
||||
|
||||
private static String getValueAttribute(AnnotationValue value) {
|
||||
return ((VariableElement) value.getValue()).getSimpleName().toString();
|
||||
}
|
||||
|
||||
public boolean hasJmx() {
|
||||
return this.types.contains("JMX");
|
||||
}
|
||||
|
||||
public boolean hasWeb() {
|
||||
return this.types.contains("WEB");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,11 +39,9 @@ import org.springframework.boot.configurationprocessor.metadata.TestJsonConverte
|
||||
import org.springframework.boot.configurationsample.endpoint.CustomPropertiesEndpoint;
|
||||
import org.springframework.boot.configurationsample.endpoint.DisabledEndpoint;
|
||||
import org.springframework.boot.configurationsample.endpoint.EnabledEndpoint;
|
||||
import org.springframework.boot.configurationsample.endpoint.OnlyJmxEndpoint;
|
||||
import org.springframework.boot.configurationsample.endpoint.OnlyWebEndpoint;
|
||||
import org.springframework.boot.configurationsample.endpoint.SimpleEndpoint;
|
||||
import org.springframework.boot.configurationsample.endpoint.SpecificEndpoint;
|
||||
import org.springframework.boot.configurationsample.endpoint.incremental.IncrementalEndpoint;
|
||||
import org.springframework.boot.configurationsample.endpoint.incremental.IncrementalJmxEndpoint;
|
||||
import org.springframework.boot.configurationsample.incremental.BarProperties;
|
||||
import org.springframework.boot.configurationsample.incremental.FooProperties;
|
||||
import org.springframework.boot.configurationsample.incremental.RenamedBarProperties;
|
||||
@@ -536,12 +534,9 @@ public class ConfigurationMetadataAnnotationProcessorTests {
|
||||
ConfigurationMetadata metadata = compile(SimpleEndpoint.class);
|
||||
assertThat(metadata).has(
|
||||
Metadata.withGroup("endpoints.simple").fromSource(SimpleEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("simple", null));
|
||||
assertThat(metadata).has(jmxEnabledFlag("simple", null));
|
||||
assertThat(metadata).has(webEnabledFlag("simple", null));
|
||||
assertThat(metadata).has(webPath("simple"));
|
||||
assertThat(metadata).has(enabledFlag("simple", true));
|
||||
assertThat(metadata).has(cacheTtl("simple"));
|
||||
assertThat(metadata.getItems()).hasSize(6);
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -550,11 +545,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
|
||||
assertThat(metadata).has(Metadata.withGroup("endpoints.disabled")
|
||||
.fromSource(DisabledEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("disabled", false));
|
||||
assertThat(metadata).has(jmxEnabledFlag("disabled", false));
|
||||
assertThat(metadata).has(webEnabledFlag("disabled", false));
|
||||
assertThat(metadata).has(webPath("disabled"));
|
||||
assertThat(metadata).has(cacheTtl("disabled"));
|
||||
assertThat(metadata.getItems()).hasSize(6);
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -563,11 +555,8 @@ public class ConfigurationMetadataAnnotationProcessorTests {
|
||||
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(webPath("enabled"));
|
||||
assertThat(metadata).has(cacheTtl("enabled"));
|
||||
assertThat(metadata.getItems()).hasSize(6);
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -577,35 +566,19 @@ public class ConfigurationMetadataAnnotationProcessorTests {
|
||||
.fromSource(CustomPropertiesEndpoint.class));
|
||||
assertThat(metadata).has(Metadata.withProperty("endpoints.customprops.name")
|
||||
.ofType(String.class).withDefaultValue("test"));
|
||||
assertThat(metadata).has(enabledFlag("customprops", null));
|
||||
assertThat(metadata).has(jmxEnabledFlag("customprops", null));
|
||||
assertThat(metadata).has(webEnabledFlag("customprops", null));
|
||||
assertThat(metadata).has(webPath("customprops"));
|
||||
assertThat(metadata).has(enabledFlag("customprops", true));
|
||||
assertThat(metadata).has(cacheTtl("customprops"));
|
||||
assertThat(metadata.getItems()).hasSize(7);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jmxOnlyEndpoint() throws IOException {
|
||||
ConfigurationMetadata metadata = compile(OnlyJmxEndpoint.class);
|
||||
assertThat(metadata).has(
|
||||
Metadata.withGroup("endpoints.jmx").fromSource(OnlyJmxEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("jmx", null));
|
||||
assertThat(metadata).has(jmxEnabledFlag("jmx", null));
|
||||
assertThat(metadata).has(cacheTtl("jmx"));
|
||||
assertThat(metadata.getItems()).hasSize(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void webOnlyEndpoint() throws IOException {
|
||||
ConfigurationMetadata metadata = compile(OnlyWebEndpoint.class);
|
||||
assertThat(metadata).has(
|
||||
Metadata.withGroup("endpoints.web").fromSource(OnlyWebEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("web", null));
|
||||
assertThat(metadata).has(webEnabledFlag("web", null));
|
||||
assertThat(metadata).has(webPath("web"));
|
||||
assertThat(metadata).has(cacheTtl("web"));
|
||||
assertThat(metadata.getItems()).hasSize(5);
|
||||
public void specificEndpoint() throws IOException {
|
||||
ConfigurationMetadata metadata = compile(SpecificEndpoint.class);
|
||||
assertThat(metadata).has(Metadata.withGroup("endpoints.specific")
|
||||
.fromSource(SpecificEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("specific", true));
|
||||
assertThat(metadata).has(cacheTtl("specific"));
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -615,74 +588,37 @@ public class ConfigurationMetadataAnnotationProcessorTests {
|
||||
ConfigurationMetadata metadata = project.fullBuild();
|
||||
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
|
||||
.fromSource(IncrementalEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("incremental", null));
|
||||
assertThat(metadata).has(jmxEnabledFlag("incremental", null));
|
||||
assertThat(metadata).has(webEnabledFlag("incremental", null));
|
||||
assertThat(metadata).has(webPath("incremental"));
|
||||
assertThat(metadata).has(enabledFlag("incremental", true));
|
||||
assertThat(metadata).has(cacheTtl("incremental"));
|
||||
assertThat(metadata.getItems()).hasSize(6);
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
project.replaceText(IncrementalEndpoint.class, "id = \"incremental\"",
|
||||
"id = \"incremental\", defaultEnablement = org.springframework.boot."
|
||||
+ "configurationsample.DefaultEnablement.DISABLED");
|
||||
"id = \"incremental\", enableByDefault = false");
|
||||
metadata = project.incrementalBuild(IncrementalEndpoint.class);
|
||||
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
|
||||
.fromSource(IncrementalEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("incremental", false));
|
||||
assertThat(metadata).has(jmxEnabledFlag("incremental", false));
|
||||
assertThat(metadata).has(webEnabledFlag("incremental", false));
|
||||
assertThat(metadata).has(webPath("incremental"));
|
||||
assertThat(metadata).has(cacheTtl("incremental"));
|
||||
assertThat(metadata.getItems()).hasSize(6);
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void incrementalEndpointBuildDisableJmxEndpoint() throws Exception {
|
||||
public void incrementalEndpointBuildEnableSpecificEndpoint() throws Exception {
|
||||
TestProject project = new TestProject(this.temporaryFolder,
|
||||
IncrementalEndpoint.class);
|
||||
SpecificEndpoint.class);
|
||||
ConfigurationMetadata metadata = project.fullBuild();
|
||||
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
|
||||
.fromSource(IncrementalEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("incremental", null));
|
||||
assertThat(metadata).has(jmxEnabledFlag("incremental", null));
|
||||
assertThat(metadata).has(webEnabledFlag("incremental", null));
|
||||
assertThat(metadata).has(webPath("incremental"));
|
||||
assertThat(metadata).has(cacheTtl("incremental"));
|
||||
assertThat(metadata.getItems()).hasSize(6);
|
||||
project.replaceText(IncrementalEndpoint.class, "id = \"incremental\"",
|
||||
"id = \"incremental\", exposure = org.springframework.boot."
|
||||
+ "configurationsample.EndpointExposure.WEB");
|
||||
metadata = project.incrementalBuild(IncrementalEndpoint.class);
|
||||
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
|
||||
.fromSource(IncrementalEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("incremental", null));
|
||||
assertThat(metadata).has(webEnabledFlag("incremental", null));
|
||||
assertThat(metadata).has(webPath("incremental"));
|
||||
assertThat(metadata).has(cacheTtl("incremental"));
|
||||
assertThat(metadata.getItems()).hasSize(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void incrementalEndpointBuildEnableJmxEndpoint() throws Exception {
|
||||
TestProject project = new TestProject(this.temporaryFolder,
|
||||
IncrementalJmxEndpoint.class);
|
||||
ConfigurationMetadata metadata = project.fullBuild();
|
||||
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
|
||||
.fromSource(IncrementalJmxEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("incremental", null));
|
||||
assertThat(metadata).has(jmxEnabledFlag("incremental", null));
|
||||
assertThat(metadata).has(cacheTtl("incremental"));
|
||||
assertThat(metadata.getItems()).hasSize(4);
|
||||
project.replaceText(IncrementalJmxEndpoint.class,
|
||||
", exposure = EndpointExposure.JMX", "");
|
||||
metadata = project.incrementalBuild(IncrementalJmxEndpoint.class);
|
||||
assertThat(metadata).has(Metadata.withGroup("endpoints.incremental")
|
||||
.fromSource(IncrementalJmxEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("incremental", null));
|
||||
assertThat(metadata).has(jmxEnabledFlag("incremental", null));
|
||||
assertThat(metadata).has(webEnabledFlag("incremental", null));
|
||||
assertThat(metadata).has(webPath("incremental"));
|
||||
assertThat(metadata).has(cacheTtl("incremental"));
|
||||
assertThat(metadata.getItems()).hasSize(6);
|
||||
assertThat(metadata).has(Metadata.withGroup("endpoints.specific")
|
||||
.fromSource(SpecificEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("specific", true));
|
||||
assertThat(metadata).has(cacheTtl("specific"));
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
project.replaceText(SpecificEndpoint.class, "enableByDefault = true",
|
||||
"enableByDefault = false");
|
||||
metadata = project.incrementalBuild(SpecificEndpoint.class);
|
||||
assertThat(metadata).has(Metadata.withGroup("endpoints.specific")
|
||||
.fromSource(SpecificEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("specific", false));
|
||||
assertThat(metadata).has(cacheTtl("specific"));
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
}
|
||||
|
||||
private Metadata.MetadataItemCondition enabledFlag(String endpointId,
|
||||
@@ -692,26 +628,6 @@ public class ConfigurationMetadataAnnotationProcessorTests {
|
||||
.withDescription(String.format("Enable the %s endpoint.", endpointId));
|
||||
}
|
||||
|
||||
private Metadata.MetadataItemCondition jmxEnabledFlag(String endpointId,
|
||||
Boolean defaultValue) {
|
||||
return Metadata.withEnabledFlag("endpoints." + endpointId + ".jmx.enabled")
|
||||
.withDefaultValue(defaultValue).withDescription(String
|
||||
.format("Expose the %s endpoint as a JMX MBean.", endpointId));
|
||||
}
|
||||
|
||||
private Metadata.MetadataItemCondition webEnabledFlag(String endpointId,
|
||||
Boolean defaultValue) {
|
||||
return Metadata.withEnabledFlag("endpoints." + endpointId + ".web.enabled")
|
||||
.withDefaultValue(defaultValue).withDescription(String
|
||||
.format("Expose the %s endpoint as a Web endpoint.", endpointId));
|
||||
}
|
||||
|
||||
private Metadata.MetadataItemCondition webPath(String endpointId) {
|
||||
return Metadata.withProperty("endpoints." + endpointId + ".web.path")
|
||||
.ofType(String.class).withDefaultValue(endpointId)
|
||||
.withDescription(String.format("Path of the %s endpoint.", endpointId));
|
||||
}
|
||||
|
||||
private Metadata.MetadataItemCondition cacheTtl(String endpointId) {
|
||||
return Metadata.withProperty("endpoints." + endpointId + ".cache.time-to-live")
|
||||
.ofType(Long.class).withDefaultValue(0).withDescription(
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
}
|
||||
@@ -33,10 +33,8 @@ import java.lang.annotation.Target;
|
||||
@Documented
|
||||
public @interface Endpoint {
|
||||
|
||||
String id();
|
||||
String id() default "";
|
||||
|
||||
DefaultEnablement defaultEnablement() default DefaultEnablement.NEUTRAL;
|
||||
|
||||
EndpointExposure[] exposure() default {};
|
||||
boolean enableByDefault() default true;
|
||||
|
||||
}
|
||||
|
||||
@@ -16,10 +16,20 @@
|
||||
|
||||
package org.springframework.boot.configurationsample;
|
||||
|
||||
public enum EndpointExposure {
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
JMX,
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Endpoint
|
||||
public @interface MetaEndpoint {
|
||||
|
||||
WEB
|
||||
String id();
|
||||
|
||||
boolean enableByDefault() default true;
|
||||
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.boot.configurationsample.endpoint;
|
||||
|
||||
import org.springframework.boot.configurationsample.DefaultEnablement;
|
||||
import org.springframework.boot.configurationsample.Endpoint;
|
||||
|
||||
/**
|
||||
@@ -24,7 +23,7 @@ import org.springframework.boot.configurationsample.Endpoint;
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Endpoint(id = "disabled", defaultEnablement = DefaultEnablement.DISABLED)
|
||||
@Endpoint(id = "disabled", enableByDefault = false)
|
||||
public class DisabledEndpoint {
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.boot.configurationsample.endpoint;
|
||||
|
||||
import org.springframework.boot.configurationsample.DefaultEnablement;
|
||||
import org.springframework.boot.configurationsample.Endpoint;
|
||||
|
||||
/**
|
||||
@@ -24,7 +23,7 @@ import org.springframework.boot.configurationsample.Endpoint;
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Endpoint(id = "enabled", defaultEnablement = DefaultEnablement.ENABLED)
|
||||
@Endpoint(id = "enabled")
|
||||
public class EnabledEndpoint {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* 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.Endpoint;
|
||||
import org.springframework.boot.configurationsample.EndpointExposure;
|
||||
|
||||
/**
|
||||
* An endpoints that only exposes a web endpoint.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Endpoint(id = "web", exposure = EndpointExposure.WEB)
|
||||
public class OnlyWebEndpoint {
|
||||
|
||||
}
|
||||
@@ -16,15 +16,15 @@
|
||||
|
||||
package org.springframework.boot.configurationsample.endpoint;
|
||||
|
||||
import org.springframework.boot.configurationsample.Endpoint;
|
||||
import org.springframework.boot.configurationsample.EndpointExposure;
|
||||
import org.springframework.boot.configurationsample.MetaEndpoint;
|
||||
|
||||
/**
|
||||
* An endpoint that only exposes a JMX MBean.
|
||||
* An meta-annotated endpoint similar to {@code @WebEndpoint} or {@code @JmxEndpoint} in
|
||||
* Boot.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Endpoint(id = "jmx", exposure = EndpointExposure.JMX)
|
||||
public class OnlyJmxEndpoint {
|
||||
@MetaEndpoint(id = "specific", enableByDefault = true)
|
||||
public class SpecificEndpoint {
|
||||
|
||||
}
|
||||
@@ -16,15 +16,15 @@
|
||||
|
||||
package org.springframework.boot.configurationsample.endpoint.incremental;
|
||||
|
||||
import org.springframework.boot.configurationsample.Endpoint;
|
||||
import org.springframework.boot.configurationsample.EndpointExposure;
|
||||
import org.springframework.boot.configurationsample.MetaEndpoint;
|
||||
|
||||
/**
|
||||
* An endpoint that only exposes a JMX MBean.
|
||||
* An meta-annotated endpoint similar to {@code @WebEndpoint} or {@code @JmxEndpoint} in
|
||||
* Boot.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Endpoint(id = "incremental", exposure = EndpointExposure.JMX)
|
||||
public class IncrementalJmxEndpoint {
|
||||
@MetaEndpoint(id = "incremental")
|
||||
public class IncrementalSpecificEndpoint {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user