Only generate time-to-live property for matching endpoints
This commit makes sure that a "cache.time-to-live" property is not generated for endpoints that do not have a main read operation (i.e. a read operation with no parameter or only nullable parameters). This matches the endpoint feature that provides caching for only such operation. Closes gh-11703
This commit is contained in:
parent
90545fb0c6
commit
5e26d04c05
|
|
@ -1241,11 +1241,9 @@ content into your application. Rather, pick only the properties that you need.
|
|||
management.endpoint.scheduledtasks.enabled= # Whether to enable the scheduled tasks endpoint.
|
||||
|
||||
# SESSIONS ENDPOINT ({sc-spring-boot-actuator}/session/SessionsEndpoint.{sc-ext}[SessionsEndpoint])
|
||||
management.endpoint.sessions.cache.time-to-live=0ms # Maximum time that a response can be cached.
|
||||
management.endpoint.sessions.enabled= # Whether to enable the sessions endpoint.
|
||||
|
||||
# SHUTDOWN ENDPOINT ({sc-spring-boot-actuator}/context/ShutdownEndpoint.{sc-ext}[ShutdownEndpoint])
|
||||
management.endpoint.shutdown.cache.time-to-live=0ms # Maximum time that a response can be cached.
|
||||
management.endpoint.shutdown.enabled=false # Whether to enable the shutdown endpoint.
|
||||
|
||||
# THREAD DUMP ENDPOINT ({sc-spring-boot-actuator}/management/ThreadDumpEndpoint.{sc-ext}[ThreadDumpEndpoint])
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 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.
|
||||
|
|
@ -46,6 +46,7 @@ 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.ElementFilter;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
|
||||
|
|
@ -83,6 +84,11 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
|
|||
static final String ENDPOINT_ANNOTATION = "org.springframework.boot.actuate."
|
||||
+ "endpoint.annotation.Endpoint";
|
||||
|
||||
static final String READ_OPERATION_ANNOTATION = "org.springframework.boot.actuate."
|
||||
+ "endpoint.annotation.ReadOperation";
|
||||
|
||||
static final String NULLABLE_ANNOTATION = "org.springframework.lang.Nullable";
|
||||
|
||||
static final String LOMBOK_DATA_ANNOTATION = "lombok.Data";
|
||||
|
||||
static final String LOMBOK_GETTER_ANNOTATION = "lombok.Getter";
|
||||
|
|
@ -118,6 +124,10 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
|
|||
return ENDPOINT_ANNOTATION;
|
||||
}
|
||||
|
||||
protected String readOperationAnnotation() {
|
||||
return READ_OPERATION_ANNOTATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceVersion getSupportedSourceVersion() {
|
||||
return SourceVersion.latestSupported();
|
||||
|
|
@ -425,9 +435,32 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
|
|||
Boolean.class.getName(), type, null,
|
||||
String.format("Whether to enable the %s endpoint.", endpointId),
|
||||
(enabledByDefault == null ? true : enabledByDefault), null));
|
||||
this.metadataCollector.add(ItemMetadata.newProperty(endpointKey,
|
||||
"cache.time-to-live", Duration.class.getName(), type, null,
|
||||
"Maximum time that a response can be cached.", 0, null));
|
||||
if (hasMainReadOperation(element)) {
|
||||
this.metadataCollector.add(ItemMetadata.newProperty(endpointKey,
|
||||
"cache.time-to-live", Duration.class.getName(), type, null,
|
||||
"Maximum time that a response can be cached.", 0, null));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasMainReadOperation(TypeElement element) {
|
||||
for (ExecutableElement method : ElementFilter
|
||||
.methodsIn(element.getEnclosedElements())) {
|
||||
if (hasAnnotation(method, readOperationAnnotation())
|
||||
&& (TypeKind.VOID != method.getReturnType().getKind())
|
||||
&& hasNoOrOptionalParameters(method)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasNoOrOptionalParameters(ExecutableElement method) {
|
||||
for (VariableElement parameter : method.getParameters()) {
|
||||
if (!hasAnnotation(parameter, NULLABLE_ANNOTATION)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isNested(Element returnType, VariableElement field,
|
||||
|
|
|
|||
|
|
@ -591,8 +591,7 @@ public class ConfigurationMetadataAnnotationProcessorTests {
|
|||
assertThat(metadata).has(Metadata.withGroup("management.endpoint.disabled")
|
||||
.fromSource(DisabledEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("disabled", false));
|
||||
assertThat(metadata).has(cacheTtl("disabled"));
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
assertThat(metadata.getItems()).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -601,8 +600,7 @@ public class ConfigurationMetadataAnnotationProcessorTests {
|
|||
assertThat(metadata).has(Metadata.withGroup("management.endpoint.enabled")
|
||||
.fromSource(EnabledEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("enabled", true));
|
||||
assertThat(metadata).has(cacheTtl("enabled"));
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
assertThat(metadata.getItems()).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -634,8 +632,7 @@ public class ConfigurationMetadataAnnotationProcessorTests {
|
|||
assertThat(metadata).has(Metadata.withGroup("management.endpoint.pascal-case")
|
||||
.fromSource(CamelCaseEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("PascalCase", "pascal-case", true));
|
||||
assertThat(metadata).has(cacheTtl("pascal-case"));
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
assertThat(metadata.getItems()).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -658,6 +655,25 @@ public class ConfigurationMetadataAnnotationProcessorTests {
|
|||
assertThat(metadata.getItems()).hasSize(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void incrementalEndpointBuildChangeCacheFlag() throws Exception {
|
||||
TestProject project = new TestProject(this.temporaryFolder,
|
||||
IncrementalEndpoint.class);
|
||||
ConfigurationMetadata metadata = project.fullBuild();
|
||||
assertThat(metadata).has(Metadata.withGroup("management.endpoint.incremental")
|
||||
.fromSource(IncrementalEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("incremental", true));
|
||||
assertThat(metadata).has(cacheTtl("incremental"));
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
project.replaceText(IncrementalEndpoint.class, "@Nullable String param",
|
||||
"String param");
|
||||
metadata = project.incrementalBuild(IncrementalEndpoint.class);
|
||||
assertThat(metadata).has(Metadata.withGroup("management.endpoint.incremental")
|
||||
.fromSource(IncrementalEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("incremental", true));
|
||||
assertThat(metadata.getItems()).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void incrementalEndpointBuildEnableSpecificEndpoint() throws Exception {
|
||||
TestProject project = new TestProject(this.temporaryFolder,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 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.
|
||||
|
|
@ -48,6 +48,8 @@ public class TestConfigurationMetadataAnnotationProcessor
|
|||
|
||||
static final String ENDPOINT_ANNOTATION = "org.springframework.boot.configurationsample.Endpoint";
|
||||
|
||||
static final String READ_OPERATION_ANNOTATION = "org.springframework.boot.configurationsample.ReadOperation";
|
||||
|
||||
private ConfigurationMetadata metadata;
|
||||
|
||||
private final File outputLocation;
|
||||
|
|
@ -76,6 +78,11 @@ public class TestConfigurationMetadataAnnotationProcessor
|
|||
return ENDPOINT_ANNOTATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String readOperationAnnotation() {
|
||||
return READ_OPERATION_ANNOTATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConfigurationMetadata writeMetaData() throws Exception {
|
||||
super.writeMetaData();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2012-2018 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;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Alternative to Spring Boot's {@code @ReadOperation} for testing (removes the need for a
|
||||
* dependency on the real annotation).
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface ReadOperation {
|
||||
|
||||
String[] produces() default {};
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 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.
|
||||
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.configurationsample.endpoint;
|
|||
|
||||
import org.springframework.boot.configurationsample.ConfigurationProperties;
|
||||
import org.springframework.boot.configurationsample.Endpoint;
|
||||
import org.springframework.boot.configurationsample.ReadOperation;
|
||||
|
||||
/**
|
||||
* An endpoint with additional custom properties.
|
||||
|
|
@ -30,6 +31,7 @@ public class CustomPropertiesEndpoint {
|
|||
|
||||
private String name = "test";
|
||||
|
||||
@ReadOperation
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 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.
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.boot.configurationsample.endpoint;
|
||||
|
||||
import org.springframework.boot.configurationsample.Endpoint;
|
||||
import org.springframework.boot.configurationsample.ReadOperation;
|
||||
|
||||
/**
|
||||
* An endpoint that is enabled unless configured explicitly.
|
||||
|
|
@ -26,4 +27,13 @@ import org.springframework.boot.configurationsample.Endpoint;
|
|||
@Endpoint(id = "enabled")
|
||||
public class EnabledEndpoint {
|
||||
|
||||
public String someMethod() {
|
||||
return "not a read operation";
|
||||
}
|
||||
|
||||
@ReadOperation
|
||||
public String retrieve(String parameter, Integer anotherParameter) {
|
||||
return "not a main read operation";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 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.
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.boot.configurationsample.endpoint;
|
||||
|
||||
import org.springframework.boot.configurationsample.Endpoint;
|
||||
import org.springframework.boot.configurationsample.ReadOperation;
|
||||
|
||||
/**
|
||||
* A simple endpoint with no default override.
|
||||
|
|
@ -26,4 +27,9 @@ import org.springframework.boot.configurationsample.Endpoint;
|
|||
@Endpoint(id = "simple")
|
||||
public class SimpleEndpoint {
|
||||
|
||||
@ReadOperation
|
||||
public String invoke() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 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.
|
||||
|
|
@ -17,14 +17,21 @@
|
|||
package org.springframework.boot.configurationsample.endpoint;
|
||||
|
||||
import org.springframework.boot.configurationsample.MetaEndpoint;
|
||||
import org.springframework.boot.configurationsample.ReadOperation;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* An meta-annotated endpoint similar to {@code @WebEndpoint} or {@code @JmxEndpoint} in
|
||||
* Boot.
|
||||
* Spring Boot. Also with a package private read operation that has an optional argument.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@MetaEndpoint(id = "specific", enableByDefault = true)
|
||||
public class SpecificEndpoint {
|
||||
|
||||
@ReadOperation
|
||||
String invoke(@Nullable String param) {
|
||||
return "test";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
package org.springframework.boot.configurationsample.endpoint.incremental;
|
||||
|
||||
import org.springframework.boot.configurationsample.Endpoint;
|
||||
import org.springframework.boot.configurationsample.ReadOperation;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* An endpoint that is enabled by default.
|
||||
|
|
@ -26,4 +28,9 @@ import org.springframework.boot.configurationsample.Endpoint;
|
|||
@Endpoint(id = "incremental")
|
||||
public class IncrementalEndpoint {
|
||||
|
||||
@ReadOperation
|
||||
public String invoke(@Nullable String param) {
|
||||
return "test";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 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.
|
||||
|
|
@ -20,7 +20,7 @@ import org.springframework.boot.configurationsample.MetaEndpoint;
|
|||
|
||||
/**
|
||||
* An meta-annotated endpoint similar to {@code @WebEndpoint} or {@code @JmxEndpoint} in
|
||||
* Boot.
|
||||
* Spring Boot.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue