mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Support mixed case endpoint IDs with time-to-live
Update the endpoint time-to-live binding logic so that mixed case endpoint IDs are supported. Prior to this commit an `InvalidConfigurationPropertyNameException` would be thrown when using a camel case endpoint ID. See gh-14773
This commit is contained in:
parent
3105a38884
commit
138d85477d
@ -19,6 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.endpoint;
|
||||
import java.time.Duration;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||
import org.springframework.boot.actuate.endpoint.invoker.cache.CachingOperationInvokerAdvisor;
|
||||
import org.springframework.boot.context.properties.bind.BindResult;
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
@ -33,7 +34,7 @@ import org.springframework.core.env.PropertyResolver;
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class EndpointIdTimeToLivePropertyFunction implements Function<String, Long> {
|
||||
class EndpointIdTimeToLivePropertyFunction implements Function<EndpointId, Long> {
|
||||
|
||||
private static final Bindable<Duration> DURATION = Bindable.of(Duration.class);
|
||||
|
||||
@ -48,9 +49,9 @@ class EndpointIdTimeToLivePropertyFunction implements Function<String, Long> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long apply(String endpointId) {
|
||||
public Long apply(EndpointId endpointId) {
|
||||
String name = String.format("management.endpoint.%s.cache.time-to-live",
|
||||
endpointId);
|
||||
endpointId.toLowerCaseString());
|
||||
BindResult<Duration> duration = Binder.get(this.environment).bind(name, DURATION);
|
||||
return duration.map(Duration::toMillis).orElse(null);
|
||||
}
|
||||
|
@ -73,8 +73,8 @@ public class CloudFoundryWebEndpointDiscovererTests {
|
||||
this.load((id) -> null, (id) -> id, configuration, consumer);
|
||||
}
|
||||
|
||||
private void load(Function<String, Long> timeToLive, PathMapper endpointPathMapper,
|
||||
Class<?> configuration,
|
||||
private void load(Function<EndpointId, Long> timeToLive,
|
||||
PathMapper endpointPathMapper, Class<?> configuration,
|
||||
Consumer<CloudFoundryWebEndpointDiscoverer> consumer) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
configuration);
|
||||
|
@ -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,6 +20,7 @@ import java.util.function.Function;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ -34,21 +35,26 @@ public class EndpointIdTimeToLivePropertyFunctionTests {
|
||||
|
||||
private final MockEnvironment environment = new MockEnvironment();
|
||||
|
||||
private final Function<String, Long> timeToLive = new EndpointIdTimeToLivePropertyFunction(
|
||||
private final Function<EndpointId, Long> timeToLive = new EndpointIdTimeToLivePropertyFunction(
|
||||
this.environment);
|
||||
|
||||
@Test
|
||||
public void defaultConfiguration() {
|
||||
Long result = this.timeToLive.apply("test");
|
||||
Long result = this.timeToLive.apply(EndpointId.of("test"));
|
||||
assertThat(result).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userConfiguration() {
|
||||
this.environment.setProperty("management.endpoint.test.cache.time-to-live",
|
||||
"500");
|
||||
Long result = this.timeToLive.apply("test");
|
||||
this.environment.setProperty(
|
||||
"management.endpoint.another-test.cache.time-to-live", "500");
|
||||
Long result = this.timeToLive.apply(EndpointId.of("anotherTest"));
|
||||
assertThat(result).isEqualTo(500L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mixedCaseUserConfiguration() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.boot.actuate.endpoint.invoker.cache;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||
import org.springframework.boot.actuate.endpoint.OperationType;
|
||||
import org.springframework.boot.actuate.endpoint.SecurityContext;
|
||||
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
|
||||
@ -33,9 +34,10 @@ import org.springframework.boot.actuate.endpoint.invoke.OperationParameters;
|
||||
*/
|
||||
public class CachingOperationInvokerAdvisor implements OperationInvokerAdvisor {
|
||||
|
||||
private final Function<String, Long> endpointIdTimeToLive;
|
||||
private final Function<EndpointId, Long> endpointIdTimeToLive;
|
||||
|
||||
public CachingOperationInvokerAdvisor(Function<String, Long> endpointIdTimeToLive) {
|
||||
public CachingOperationInvokerAdvisor(
|
||||
Function<EndpointId, Long> endpointIdTimeToLive) {
|
||||
this.endpointIdTimeToLive = endpointIdTimeToLive;
|
||||
}
|
||||
|
||||
@ -43,6 +45,12 @@ public class CachingOperationInvokerAdvisor implements OperationInvokerAdvisor {
|
||||
@Deprecated
|
||||
public OperationInvoker apply(String endpointId, OperationType operationType,
|
||||
OperationParameters parameters, OperationInvoker invoker) {
|
||||
return apply(EndpointId.of(endpointId), operationType, parameters, invoker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationInvoker apply(EndpointId endpointId, OperationType operationType,
|
||||
OperationParameters parameters, OperationInvoker invoker) {
|
||||
if (operationType == OperationType.READ && !hasMandatoryParameter(parameters)) {
|
||||
Long timeToLive = this.endpointIdTimeToLive.apply(endpointId);
|
||||
if (timeToLive != null && timeToLive > 0) {
|
||||
|
@ -500,12 +500,12 @@ public class EndpointDiscovererTests {
|
||||
}
|
||||
|
||||
TestEndpointDiscoverer(ApplicationContext applicationContext,
|
||||
Function<String, Long> timeToLive) {
|
||||
Function<EndpointId, Long> timeToLive) {
|
||||
this(applicationContext, timeToLive, Collections.emptyList());
|
||||
}
|
||||
|
||||
TestEndpointDiscoverer(ApplicationContext applicationContext,
|
||||
Function<String, Long> timeToLive,
|
||||
Function<EndpointId, Long> timeToLive,
|
||||
Collection<EndpointFilter<TestExposableEndpoint>> filters) {
|
||||
this(applicationContext, new ConversionServiceParameterValueMapper(),
|
||||
Collections.singleton(new CachingOperationInvokerAdvisor(timeToLive)),
|
||||
|
@ -51,7 +51,7 @@ public class CachingOperationInvokerAdvisorTests {
|
||||
private OperationInvoker invoker;
|
||||
|
||||
@Mock
|
||||
private Function<String, Long> timeToLive;
|
||||
private Function<EndpointId, Long> timeToLive;
|
||||
|
||||
private CachingOperationInvokerAdvisor advisor;
|
||||
|
||||
@ -85,7 +85,7 @@ public class CachingOperationInvokerAdvisorTests {
|
||||
OperationInvoker advised = this.advisor.apply(EndpointId.of("foo"),
|
||||
OperationType.READ, parameters, this.invoker);
|
||||
assertThat(advised).isSameAs(this.invoker);
|
||||
verify(this.timeToLive).apply("foo");
|
||||
verify(this.timeToLive).apply(EndpointId.of("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -95,7 +95,7 @@ public class CachingOperationInvokerAdvisorTests {
|
||||
OperationInvoker advised = this.advisor.apply(EndpointId.of("foo"),
|
||||
OperationType.READ, parameters, this.invoker);
|
||||
assertThat(advised).isSameAs(this.invoker);
|
||||
verify(this.timeToLive).apply("foo");
|
||||
verify(this.timeToLive).apply(EndpointId.of("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -306,7 +306,7 @@ public class JmxEndpointDiscovererTests {
|
||||
load(configuration, (id) -> null, consumer);
|
||||
}
|
||||
|
||||
private void load(Class<?> configuration, Function<String, Long> timeToLive,
|
||||
private void load(Class<?> configuration, Function<EndpointId, Long> timeToLive,
|
||||
Consumer<JmxEndpointDiscoverer> consumer) {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
configuration)) {
|
||||
|
@ -257,8 +257,9 @@ public class WebEndpointDiscovererTests {
|
||||
this.load((id) -> null, (id) -> id, configuration, consumer);
|
||||
}
|
||||
|
||||
private void load(Function<String, Long> timeToLive, PathMapper endpointPathMapper,
|
||||
Class<?> configuration, Consumer<WebEndpointDiscoverer> consumer) {
|
||||
private void load(Function<EndpointId, Long> timeToLive,
|
||||
PathMapper endpointPathMapper, Class<?> configuration,
|
||||
Consumer<WebEndpointDiscoverer> consumer) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
configuration);
|
||||
try {
|
||||
|
Loading…
Reference in New Issue
Block a user