Skip to content

Commit c849a0a

Browse files
committed
Cache /health response irrespective of sensitivity and security
Previously, the response from /health was not cached if the request was secure, i.e. the user has authenticated, or the endpoint was configured as not being sensitive. The commit updates HealthMvcEndpoint to apply the caching logic all the time. Users that do not want caching can disable it by configuring the TTL with a value of zero. Closes gh-2630
1 parent 0a38b9b commit c849a0a

File tree

2 files changed

+15
-27
lines changed

2 files changed

+15
-27
lines changed

spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpoint.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2014 the original author or authors.
2+
* Copyright 2012-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -137,11 +137,11 @@ public Object invoke(Principal principal) {
137137

138138
private Health getHealth(Principal principal) {
139139
long accessTime = System.currentTimeMillis();
140-
if (isCacheStale(accessTime) || isSecure(principal) || isUnrestricted()) {
140+
if (isCacheStale(accessTime)) {
141141
this.lastAccess = accessTime;
142142
this.cached = this.delegate.invoke();
143143
}
144-
if (isSecure(principal) || isUnrestricted()) {
144+
if (exposeHealthDetails(principal)) {
145145
return this.cached;
146146
}
147147
return Health.status(this.cached.getStatus()).build();
@@ -154,16 +154,20 @@ private boolean isCacheStale(long accessTime) {
154154
return (accessTime - this.lastAccess) > this.delegate.getTimeToLive();
155155
}
156156

157-
private boolean isUnrestricted() {
158-
Boolean sensitive = this.propertyResolver.getProperty("sensitive", Boolean.class);
159-
return !this.secure || Boolean.FALSE.equals(sensitive);
157+
private boolean exposeHealthDetails(Principal principal) {
158+
return isSecure(principal) || isUnrestricted();
160159
}
161160

162161
private boolean isSecure(Principal principal) {
163162
return (principal != null && !principal.getClass().getName()
164163
.contains("Anonymous"));
165164
}
166165

166+
private boolean isUnrestricted() {
167+
Boolean sensitive = this.propertyResolver.getProperty("sensitive", Boolean.class);
168+
return !this.secure || Boolean.FALSE.equals(sensitive);
169+
}
170+
167171
@Override
168172
public String getPath() {
169173
return "/" + this.delegate.getId();

spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HealthMvcEndpointTests.java

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2014 the original author or authors.
2+
* Copyright 2012-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -44,6 +44,7 @@
4444
*
4545
* @author Christian Dupuis
4646
* @author Dave Syer
47+
* @author Andy Wilkinson
4748
*/
4849
public class HealthMvcEndpointTests {
4950

@@ -115,23 +116,7 @@ public void secure() {
115116
}
116117

117118
@Test
118-
public void secureNotCached() {
119-
given(this.endpoint.getTimeToLive()).willReturn(10000L);
120-
given(this.endpoint.isSensitive()).willReturn(false);
121-
given(this.endpoint.invoke()).willReturn(
122-
new Health.Builder().up().withDetail("foo", "bar").build());
123-
Object result = this.mvc.invoke(this.user);
124-
assertTrue(result instanceof Health);
125-
assertTrue(((Health) result).getStatus() == Status.UP);
126-
given(this.endpoint.invoke()).willReturn(new Health.Builder().down().build());
127-
result = this.mvc.invoke(this.user);
128-
@SuppressWarnings("unchecked")
129-
Health health = ((ResponseEntity<Health>) result).getBody();
130-
assertTrue(health.getStatus() == Status.DOWN);
131-
}
132-
133-
@Test
134-
public void unsecureCached() {
119+
public void healthIsCached() {
135120
given(this.endpoint.getTimeToLive()).willReturn(10000L);
136121
given(this.endpoint.isSensitive()).willReturn(true);
137122
given(this.endpoint.invoke()).willReturn(
@@ -164,9 +149,8 @@ public void unsecureAnonymousAccessUnrestricted() {
164149
}
165150

166151
@Test
167-
public void unsecureIsNotCachedWhenAnonymousAccessIsUnrestricted() {
168-
this.environment.getPropertySources().addLast(NON_SENSITIVE);
169-
given(this.endpoint.getTimeToLive()).willReturn(10000L);
152+
public void noCachingWhenTimeToLiveIsZero() {
153+
given(this.endpoint.getTimeToLive()).willReturn(0L);
170154
given(this.endpoint.invoke()).willReturn(
171155
new Health.Builder().up().withDetail("foo", "bar").build());
172156
Object result = this.mvc.invoke(null);

0 commit comments

Comments
 (0)