Skip to content

Commit d72a9d9

Browse files
committed
Allow EndpointRequest to match additional paths
Add `toAdditionalPaths(...)` methods on the servlet and reactive `EndpointRequest` classes to support matching of additional paths. A new `AdditionalPathsMapper` interface provides the mappings between endpoint IDs and any additional paths that they might use. The existing `AutoConfiguredHealthEndpointGroups` class has been updated to implement the interface. Auto-configurations have also been updated so that additional health endpoint paths (typically `/livez` and `/readyz`) are permitted when using Spring Security without any custom configuration. Fixes gh-40962
1 parent f5b6514 commit d72a9d9

26 files changed

+900
-200
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscoverer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public CloudFoundryWebEndpointDiscoverer(ApplicationContext applicationContext,
5959
ParameterValueMapper parameterValueMapper, EndpointMediaTypes endpointMediaTypes,
6060
List<PathMapper> endpointPathMappers, Collection<OperationInvokerAdvisor> invokerAdvisors,
6161
Collection<EndpointFilter<ExposableWebEndpoint>> filters) {
62-
super(applicationContext, parameterValueMapper, endpointMediaTypes, endpointPathMappers, invokerAdvisors,
62+
super(applicationContext, parameterValueMapper, endpointMediaTypes, endpointPathMappers, null, invokerAdvisors,
6363
filters);
6464
}
6565

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointAutoConfiguration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
2929
import org.springframework.boot.actuate.endpoint.invoke.OperationInvokerAdvisor;
3030
import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper;
31+
import org.springframework.boot.actuate.endpoint.web.AdditionalPathsMapper;
3132
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
3233
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
3334
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints;
@@ -81,11 +82,12 @@ public EndpointMediaTypes endpointMediaTypes() {
8182
@ConditionalOnMissingBean(WebEndpointsSupplier.class)
8283
public WebEndpointDiscoverer webEndpointDiscoverer(ParameterValueMapper parameterValueMapper,
8384
EndpointMediaTypes endpointMediaTypes, ObjectProvider<PathMapper> endpointPathMappers,
85+
ObjectProvider<AdditionalPathsMapper> additionalPathsMappers,
8486
ObjectProvider<OperationInvokerAdvisor> invokerAdvisors,
8587
ObjectProvider<EndpointFilter<ExposableWebEndpoint>> filters) {
8688
return new WebEndpointDiscoverer(this.applicationContext, parameterValueMapper, endpointMediaTypes,
87-
endpointPathMappers.orderedStream().toList(), invokerAdvisors.orderedStream().toList(),
88-
filters.orderedStream().toList());
89+
endpointPathMappers.orderedStream().toList(), additionalPathsMappers.orderedStream().toList(),
90+
invokerAdvisors.orderedStream().toList(), filters.orderedStream().toList());
8991
}
9092

9193
@Bean

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AutoConfiguredHealthEndpointGroups.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -21,9 +21,11 @@
2121
import java.util.LinkedHashMap;
2222
import java.util.List;
2323
import java.util.Map;
24+
import java.util.Objects;
2425
import java.util.Set;
2526
import java.util.function.Predicate;
2627
import java.util.function.Supplier;
28+
import java.util.stream.Stream;
2729

2830
import org.springframework.beans.factory.BeanFactory;
2931
import org.springframework.beans.factory.BeanFactoryUtils;
@@ -32,8 +34,12 @@
3234
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
3335
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointProperties.Group;
3436
import org.springframework.boot.actuate.autoconfigure.health.HealthProperties.Status;
37+
import org.springframework.boot.actuate.endpoint.EndpointId;
3538
import org.springframework.boot.actuate.endpoint.Show;
39+
import org.springframework.boot.actuate.endpoint.web.AdditionalPathsMapper;
40+
import org.springframework.boot.actuate.endpoint.web.WebServerNamespace;
3641
import org.springframework.boot.actuate.health.AdditionalHealthEndpointPath;
42+
import org.springframework.boot.actuate.health.HealthEndpoint;
3743
import org.springframework.boot.actuate.health.HealthEndpointGroup;
3844
import org.springframework.boot.actuate.health.HealthEndpointGroups;
3945
import org.springframework.boot.actuate.health.HttpCodeStatusMapper;
@@ -51,7 +57,7 @@
5157
* @author Phillip Webb
5258
* @author Madhura Bhave
5359
*/
54-
class AutoConfiguredHealthEndpointGroups implements HealthEndpointGroups {
60+
class AutoConfiguredHealthEndpointGroups implements HealthEndpointGroups, AdditionalPathsMapper {
5561

5662
private static final Predicate<String> ALL = (name) -> true;
5763

@@ -159,4 +165,20 @@ public HealthEndpointGroup get(String name) {
159165
return this.groups.get(name);
160166
}
161167

168+
@Override
169+
public List<String> getAdditionalPaths(EndpointId endpointId, WebServerNamespace webServerNamespace) {
170+
if (!HealthEndpoint.ID.equals(endpointId)) {
171+
return null;
172+
}
173+
return streamAllGroups().map(HealthEndpointGroup::getAdditionalPath)
174+
.filter(Objects::nonNull)
175+
.filter((additionalPath) -> additionalPath.hasNamespace(webServerNamespace))
176+
.map(AdditionalHealthEndpointPath::getValue)
177+
.toList();
178+
}
179+
180+
private Stream<HealthEndpointGroup> streamAllGroups() {
181+
return Stream.concat(Stream.of(this.primaryGroup), this.groups.values().stream());
182+
}
183+
162184
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 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.
@@ -73,8 +73,8 @@ HttpCodeStatusMapper healthHttpCodeStatusMapper(HealthEndpointProperties propert
7373
}
7474

7575
@Bean
76-
@ConditionalOnMissingBean
77-
HealthEndpointGroups healthEndpointGroups(ApplicationContext applicationContext,
76+
@ConditionalOnMissingBean(HealthEndpointGroups.class)
77+
AutoConfiguredHealthEndpointGroups healthEndpointGroups(ApplicationContext applicationContext,
7878
HealthEndpointProperties properties) {
7979
return new AutoConfiguredHealthEndpointGroups(applicationContext, properties);
8080
}

0 commit comments

Comments
 (0)