Browse Source

Merge branch '2.2.x'

Closes gh-19090
pull/19094/head
Stephane Nicoll 6 years ago
parent
commit
f540e7eae9
  1. 10
      spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/invoker/cache/CachingOperationInvoker.java
  2. 4
      spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/invoker/cache/CachingOperationInvokerAdvisor.java
  3. 12
      spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/invoker/cache/CachingOperationInvokerAdvisorTests.java
  4. 21
      spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/invoker/cache/CachingOperationInvokerTests.java

10
spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/invoker/cache/CachingOperationInvoker.java vendored

@ -19,11 +19,13 @@ package org.springframework.boot.actuate.endpoint.invoker.cache;
import java.time.Duration; import java.time.Duration;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.endpoint.InvocationContext; import org.springframework.boot.actuate.endpoint.InvocationContext;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker; import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
@ -46,7 +48,7 @@ public class CachingOperationInvoker implements OperationInvoker {
private final long timeToLive; private final long timeToLive;
private volatile CachedResponse cachedResponse; private final Map<ApiVersion, CachedResponse> cachedResponses;
/** /**
* Create a new instance with the target {@link OperationInvoker} to use to compute * Create a new instance with the target {@link OperationInvoker} to use to compute
@ -58,6 +60,7 @@ public class CachingOperationInvoker implements OperationInvoker {
Assert.isTrue(timeToLive > 0, "TimeToLive must be strictly positive"); Assert.isTrue(timeToLive > 0, "TimeToLive must be strictly positive");
this.invoker = invoker; this.invoker = invoker;
this.timeToLive = timeToLive; this.timeToLive = timeToLive;
this.cachedResponses = new ConcurrentHashMap<>();
} }
/** /**
@ -74,11 +77,12 @@ public class CachingOperationInvoker implements OperationInvoker {
return this.invoker.invoke(context); return this.invoker.invoke(context);
} }
long accessTime = System.currentTimeMillis(); long accessTime = System.currentTimeMillis();
CachedResponse cached = this.cachedResponse; ApiVersion contextApiVersion = context.getApiVersion();
CachedResponse cached = this.cachedResponses.get(contextApiVersion);
if (cached == null || cached.isStale(accessTime, this.timeToLive)) { if (cached == null || cached.isStale(accessTime, this.timeToLive)) {
Object response = this.invoker.invoke(context); Object response = this.invoker.invoke(context);
cached = createCachedResponse(response, accessTime); cached = createCachedResponse(response, accessTime);
this.cachedResponse = cached; this.cachedResponses.put(contextApiVersion, cached);
} }
return cached.getResponse(); return cached.getResponse();
} }

4
spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/invoker/cache/CachingOperationInvokerAdvisor.java vendored

@ -21,6 +21,7 @@ import java.util.function.Function;
import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.EndpointId;
import org.springframework.boot.actuate.endpoint.OperationType; import org.springframework.boot.actuate.endpoint.OperationType;
import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker; import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
import org.springframework.boot.actuate.endpoint.invoke.OperationInvokerAdvisor; import org.springframework.boot.actuate.endpoint.invoke.OperationInvokerAdvisor;
import org.springframework.boot.actuate.endpoint.invoke.OperationParameter; import org.springframework.boot.actuate.endpoint.invoke.OperationParameter;
@ -54,7 +55,8 @@ public class CachingOperationInvokerAdvisor implements OperationInvokerAdvisor {
private boolean hasMandatoryParameter(OperationParameters parameters) { private boolean hasMandatoryParameter(OperationParameters parameters) {
for (OperationParameter parameter : parameters) { for (OperationParameter parameter : parameters) {
if (parameter.isMandatory() && !SecurityContext.class.isAssignableFrom(parameter.getType())) { if (parameter.isMandatory() && !ApiVersion.class.isAssignableFrom(parameter.getType())
&& !SecurityContext.class.isAssignableFrom(parameter.getType())) {
return true; return true;
} }
} }

12
spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/invoker/cache/CachingOperationInvokerAdvisorTests.java vendored

@ -27,6 +27,7 @@ import org.mockito.MockitoAnnotations;
import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.EndpointId;
import org.springframework.boot.actuate.endpoint.OperationType; import org.springframework.boot.actuate.endpoint.OperationType;
import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker; import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
import org.springframework.boot.actuate.endpoint.invoke.OperationParameters; import org.springframework.boot.actuate.endpoint.invoke.OperationParameters;
import org.springframework.boot.actuate.endpoint.invoke.reflect.OperationMethod; import org.springframework.boot.actuate.endpoint.invoke.reflect.OperationMethod;
@ -117,6 +118,13 @@ class CachingOperationInvokerAdvisorTests {
assertAdviseIsApplied(parameters); assertAdviseIsApplied(parameters);
} }
@Test
void applyWithApiVersionShouldAddAdvise() {
OperationParameters parameters = getParameters("getWithApiVersion", ApiVersion.class, String.class);
given(this.timeToLive.apply(any())).willReturn(100L);
assertAdviseIsApplied(parameters);
}
private void assertAdviseIsApplied(OperationParameters parameters) { private void assertAdviseIsApplied(OperationParameters parameters) {
OperationInvoker advised = this.advisor.apply(EndpointId.of("foo"), OperationType.READ, parameters, OperationInvoker advised = this.advisor.apply(EndpointId.of("foo"), OperationType.READ, parameters,
this.invoker); this.invoker);
@ -152,6 +160,10 @@ class CachingOperationInvokerAdvisorTests {
return ""; return "";
} }
String getWithApiVersion(ApiVersion apiVersion, @Nullable String bar) {
return "";
}
} }
} }

21
spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/invoker/cache/CachingOperationInvokerTests.java vendored

@ -28,6 +28,7 @@ import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.endpoint.InvocationContext; import org.springframework.boot.actuate.endpoint.InvocationContext;
import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.endpoint.SecurityContext;
import org.springframework.boot.actuate.endpoint.http.ApiVersion;
import org.springframework.boot.actuate.endpoint.invoke.MissingParametersException; import org.springframework.boot.actuate.endpoint.invoke.MissingParametersException;
import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker; import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker;
@ -152,6 +153,26 @@ class CachingOperationInvokerTests {
verify(target, times(2)).invoke(context); verify(target, times(2)).invoke(context);
} }
@Test
void targetInvokedWithDifferentApiVersion() {
OperationInvoker target = mock(OperationInvoker.class);
Object expectedV2 = new Object();
Object expectedV3 = new Object();
InvocationContext contextV2 = new InvocationContext(ApiVersion.V2, mock(SecurityContext.class),
Collections.emptyMap());
InvocationContext contextV3 = new InvocationContext(ApiVersion.V3, mock(SecurityContext.class),
Collections.emptyMap());
given(target.invoke(contextV2)).willReturn(expectedV2);
given(target.invoke(contextV3)).willReturn(expectedV3);
CachingOperationInvoker invoker = new CachingOperationInvoker(target, 500L);
Object response = invoker.invoke(contextV2);
assertThat(response).isSameAs(expectedV2);
verify(target, times(1)).invoke(contextV2);
Object cachedResponse = invoker.invoke(contextV3);
assertThat(cachedResponse).isNotSameAs(response);
verify(target, times(1)).invoke(contextV3);
}
private static class MonoOperationInvoker implements OperationInvoker { private static class MonoOperationInvoker implements OperationInvoker {
static int invocations; static int invocations;

Loading…
Cancel
Save