Skip to content

Commit 695e192

Browse files
committed
Retain probe defaults when configuring other properties on probe health groups
Closes gh-40268 Signed-off-by: htjworld <116538001+htjworld@users.noreply.github.com>
1 parent bcf4c32 commit 695e192

7 files changed

Lines changed: 175 additions & 46 deletions

File tree

module/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/actuate/endpoint/AvailabilityProbesAutoConfiguration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2424
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2525
import org.springframework.boot.availability.ApplicationAvailability;
26+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
2627
import org.springframework.boot.health.application.LivenessStateHealthIndicator;
2728
import org.springframework.boot.health.application.ReadinessStateHealthIndicator;
2829
import org.springframework.boot.health.autoconfigure.application.AvailabilityHealthContributorAutoConfiguration;
@@ -40,6 +41,7 @@
4041
ApplicationAvailabilityAutoConfiguration.class })
4142
@ConditionalOnClass(name = "org.springframework.boot.actuate.endpoint.annotation.Endpoint")
4243
@ConditionalOnBooleanProperty(name = "management.endpoint.health.probes.enabled", matchIfMissing = true)
44+
@EnableConfigurationProperties(HealthEndpointProperties.class)
4345
public final class AvailabilityProbesAutoConfiguration {
4446

4547
@Bean
@@ -56,8 +58,8 @@ ReadinessStateHealthIndicator readinessStateHealthIndicator(ApplicationAvailabil
5658

5759
@Bean
5860
AvailabilityProbesHealthEndpointGroupsPostProcessor availabilityProbesHealthEndpointGroupsPostProcessor(
59-
Environment environment) {
60-
return new AvailabilityProbesHealthEndpointGroupsPostProcessor(environment);
61+
Environment environment, HealthEndpointProperties properties) {
62+
return new AvailabilityProbesHealthEndpointGroupsPostProcessor(environment, properties);
6163
}
6264

6365
}

module/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/actuate/endpoint/AvailabilityProbesHealthEndpointGroups.java

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,27 @@
4242
* @author Phillip Webb
4343
* @author Brian Clozel
4444
* @author Madhura Bhave
45+
* @author htjworld
4546
*/
4647
class AvailabilityProbesHealthEndpointGroups implements HealthEndpointGroups, AdditionalPathsMapper {
4748

49+
private static final String LIVENESS = "liveness";
50+
51+
private static final String READINESS = "readiness";
52+
4853
private final HealthEndpointGroups groups;
4954

55+
private final HealthEndpointProperties properties;
56+
5057
private final Map<String, HealthEndpointGroup> probeGroups;
5158

5259
private final Set<String> names;
5360

54-
private static final String LIVENESS = "liveness";
55-
56-
private static final String READINESS = "readiness";
57-
58-
AvailabilityProbesHealthEndpointGroups(HealthEndpointGroups groups, boolean addAdditionalPaths) {
61+
AvailabilityProbesHealthEndpointGroups(HealthEndpointGroups groups, boolean addAdditionalPaths,
62+
HealthEndpointProperties properties) {
5963
Assert.notNull(groups, "'groups' must not be null");
6064
this.groups = groups;
65+
this.properties = properties;
6166
this.probeGroups = createProbeGroups(addAdditionalPaths);
6267
Set<String> names = new LinkedHashSet<>(groups.getNames());
6368
names.addAll(this.probeGroups.keySet());
@@ -75,19 +80,34 @@ private HealthEndpointGroup getOrCreateProbeGroup(boolean addAdditionalPath, Str
7580
String members) {
7681
HealthEndpointGroup group = this.groups.get(name);
7782
if (group != null) {
78-
return determineAdditionalPathForExistingGroup(addAdditionalPath, path, group);
83+
if (hasExplicitMembership(name)) {
84+
return determineAdditionalPathForExistingGroup(addAdditionalPath, path, group);
85+
}
86+
return retainProbeDefaultsForExistingGroup(addAdditionalPath, path, group, members);
7987
}
8088
AdditionalHealthEndpointPath additionalPath = (!addAdditionalPath) ? null
8189
: AdditionalHealthEndpointPath.of(WebServerNamespace.SERVER, path);
8290
return new AvailabilityProbesHealthEndpointGroup(additionalPath, members);
8391
}
8492

93+
private boolean hasExplicitMembership(String name) {
94+
HealthEndpointProperties.Group group = this.properties.getGroup().get(name);
95+
return group != null && (group.getInclude() != null || group.getExclude() != null);
96+
}
97+
98+
private HealthEndpointGroup retainProbeDefaultsForExistingGroup(boolean addAdditionalPath, String path,
99+
HealthEndpointGroup group, String members) {
100+
AdditionalHealthEndpointPath additionalPath = (addAdditionalPath && group.getAdditionalPath() == null)
101+
? AdditionalHealthEndpointPath.of(WebServerNamespace.SERVER, path) : null;
102+
return new DelegatingAvailabilityProbesHealthEndpointGroup(group, additionalPath, Set.of(members));
103+
}
104+
85105
private HealthEndpointGroup determineAdditionalPathForExistingGroup(boolean addAdditionalPath, String path,
86106
HealthEndpointGroup group) {
87107
if (addAdditionalPath && group.getAdditionalPath() == null) {
88108
AdditionalHealthEndpointPath additionalPath = AdditionalHealthEndpointPath.of(WebServerNamespace.SERVER,
89109
path);
90-
return new DelegatingAvailabilityProbesHealthEndpointGroup(group, additionalPath);
110+
return new DelegatingAvailabilityProbesHealthEndpointGroup(group, additionalPath, null);
91111
}
92112
return group;
93113
}

module/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/actuate/endpoint/AvailabilityProbesHealthEndpointGroupsPostProcessor.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,24 @@
2828
*
2929
* @author Phillip Webb
3030
* @author Madhura Bhave
31+
* @author htjworld
3132
*/
3233
@Order(Ordered.LOWEST_PRECEDENCE)
3334
class AvailabilityProbesHealthEndpointGroupsPostProcessor implements HealthEndpointGroupsPostProcessor {
3435

3536
private final boolean addAdditionalPaths;
3637

37-
AvailabilityProbesHealthEndpointGroupsPostProcessor(Environment environment) {
38+
private final HealthEndpointProperties properties;
39+
40+
AvailabilityProbesHealthEndpointGroupsPostProcessor(Environment environment, HealthEndpointProperties properties) {
3841
this.addAdditionalPaths = "true"
3942
.equalsIgnoreCase(environment.getProperty("management.endpoint.health.probes.add-additional-paths"));
43+
this.properties = properties;
4044
}
4145

4246
@Override
4347
public HealthEndpointGroups postProcessHealthEndpointGroups(HealthEndpointGroups groups) {
44-
return new AvailabilityProbesHealthEndpointGroups(groups, this.addAdditionalPaths);
48+
return new AvailabilityProbesHealthEndpointGroups(groups, this.addAdditionalPaths, this.properties);
4549
}
4650

4751
}

module/spring-boot-health/src/main/java/org/springframework/boot/health/autoconfigure/actuate/endpoint/DelegatingAvailabilityProbesHealthEndpointGroup.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
package org.springframework.boot.health.autoconfigure.actuate.endpoint;
1818

19+
import java.util.Set;
20+
21+
import org.jspecify.annotations.Nullable;
22+
1923
import org.springframework.boot.actuate.endpoint.SecurityContext;
2024
import org.springframework.boot.health.actuate.endpoint.AdditionalHealthEndpointPath;
2125
import org.springframework.boot.health.actuate.endpoint.HealthEndpointGroup;
@@ -28,23 +32,27 @@
2832
* existing group.
2933
*
3034
* @author Madhura Bhave
35+
* @author htjworld
3136
*/
3237
class DelegatingAvailabilityProbesHealthEndpointGroup implements HealthEndpointGroup {
3338

3439
private final HealthEndpointGroup delegate;
3540

36-
private final AdditionalHealthEndpointPath additionalPath;
41+
private final @Nullable AdditionalHealthEndpointPath additionalPath;
42+
43+
private final @Nullable Set<String> members;
3744

3845
DelegatingAvailabilityProbesHealthEndpointGroup(HealthEndpointGroup delegate,
39-
AdditionalHealthEndpointPath additionalPath) {
46+
@Nullable AdditionalHealthEndpointPath additionalPath, @Nullable Set<String> members) {
4047
Assert.notNull(delegate, "'delegate' must not be null");
4148
this.delegate = delegate;
4249
this.additionalPath = additionalPath;
50+
this.members = members;
4351
}
4452

4553
@Override
4654
public boolean isMember(String name) {
47-
return this.delegate.isMember(name);
55+
return (this.members != null) ? this.members.contains(name) : this.delegate.isMember(name);
4856
}
4957

5058
@Override
@@ -68,8 +76,8 @@ public HttpCodeStatusMapper getHttpCodeStatusMapper() {
6876
}
6977

7078
@Override
71-
public AdditionalHealthEndpointPath getAdditionalPath() {
72-
return this.additionalPath;
79+
public @Nullable AdditionalHealthEndpointPath getAdditionalPath() {
80+
return (this.additionalPath != null) ? this.additionalPath : this.delegate.getAdditionalPath();
7381
}
7482

7583
}

module/spring-boot-health/src/test/java/org/springframework/boot/health/autoconfigure/actuate/endpoint/AvailabilityProbesHealthEndpointGroupsPostProcessorTests.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
class AvailabilityProbesHealthEndpointGroupsPostProcessorTests {
4444

4545
private final AvailabilityProbesHealthEndpointGroupsPostProcessor postProcessor = new AvailabilityProbesHealthEndpointGroupsPostProcessor(
46-
new MockEnvironment());
46+
new MockEnvironment(), new HealthEndpointProperties());
4747

4848
@Test
4949
void postProcessHealthEndpointGroupsWhenGroupsAlreadyContainedReturnsOriginal() {
@@ -102,7 +102,7 @@ void postProcessHealthEndpointGroupsWhenGroupsAlreadyContainedAndAdditionalPathP
102102
MockEnvironment environment = new MockEnvironment();
103103
environment.setProperty("management.endpoint.health.probes.add-additional-paths", "true");
104104
AvailabilityProbesHealthEndpointGroupsPostProcessor postProcessor = new AvailabilityProbesHealthEndpointGroupsPostProcessor(
105-
environment);
105+
environment, new HealthEndpointProperties());
106106
HealthEndpointGroups postProcessed = postProcessor.postProcessHealthEndpointGroups(groups);
107107
HealthEndpointGroup liveness = postProcessed.get("liveness");
108108
assertThat(liveness).isNotNull();
@@ -120,7 +120,7 @@ void delegatesAdditionalPathMappingToOriginalBean() {
120120
.willReturn(List.of("/one", "/two", "/three"));
121121
MockEnvironment environment = new MockEnvironment();
122122
AvailabilityProbesHealthEndpointGroupsPostProcessor postProcessor = new AvailabilityProbesHealthEndpointGroupsPostProcessor(
123-
environment);
123+
environment, new HealthEndpointProperties());
124124
HealthEndpointGroups postProcessed = postProcessor.postProcessHealthEndpointGroups(groups);
125125
assertThat(postProcessed).isInstanceOf(AdditionalPathsMapper.class);
126126
AdditionalPathsMapper additionalPathsMapper = (AdditionalPathsMapper) postProcessed;
@@ -137,7 +137,7 @@ void whenAddAdditionalPathsIsTrueThenIncludesOwnAdditionalPathsInGetAdditionalPa
137137
MockEnvironment environment = new MockEnvironment();
138138
environment.setProperty("management.endpoint.health.probes.add-additional-paths", "true");
139139
AvailabilityProbesHealthEndpointGroupsPostProcessor postProcessor = new AvailabilityProbesHealthEndpointGroupsPostProcessor(
140-
environment);
140+
environment, new HealthEndpointProperties());
141141
HealthEndpointGroups postProcessed = postProcessor.postProcessHealthEndpointGroups(groups);
142142
assertThat(postProcessed).isInstanceOf(AdditionalPathsMapper.class);
143143
AdditionalPathsMapper additionalPathsMapper = (AdditionalPathsMapper) postProcessed;
@@ -149,7 +149,7 @@ private HealthEndpointGroups getPostProcessed(String value) {
149149
MockEnvironment environment = new MockEnvironment();
150150
environment.setProperty("management.endpoint.health.probes.add-additional-paths", value);
151151
AvailabilityProbesHealthEndpointGroupsPostProcessor postProcessor = new AvailabilityProbesHealthEndpointGroupsPostProcessor(
152-
environment);
152+
environment, new HealthEndpointProperties());
153153
HealthEndpointGroups groups = mock(HealthEndpointGroups.class);
154154
return postProcessor.postProcessHealthEndpointGroups(groups);
155155
}

0 commit comments

Comments
 (0)