Skip to content

Commit c937bb6

Browse files
committed
ServletEndpoints should take servletPath into account
Fixes gh-13106
1 parent fbf9744 commit c937bb6

File tree

2 files changed

+78
-10
lines changed

2 files changed

+78
-10
lines changed

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

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,35 @@
1616

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

19+
import org.glassfish.jersey.server.ResourceConfig;
20+
1921
import org.springframework.boot.actuate.autoconfigure.endpoint.ExposeExcludePropertyEndpointFilter;
2022
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
2123
import org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint;
2224
import org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar;
2325
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
26+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
27+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
2428
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
2529
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
30+
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPathProvider;
31+
import org.springframework.context.ApplicationContext;
2632
import org.springframework.context.annotation.Bean;
2733
import org.springframework.context.annotation.Configuration;
34+
import org.springframework.web.servlet.DispatcherServlet;
2835

2936
/**
3037
* {@link ManagementContextConfiguration} for servlet endpoints.
3138
*
3239
* @author Phillip Webb
3340
* @author Andy Wilkinson
41+
* @author Madhura Bhave
3442
* @since 2.0.0
3543
*/
3644
@Configuration
3745
@ConditionalOnWebApplication(type = Type.SERVLET)
3846
public class ServletEndpointManagementContextConfiguration {
3947

40-
@Bean
41-
public ServletEndpointRegistrar servletEndpointRegistrar(
42-
WebEndpointProperties properties,
43-
ServletEndpointsSupplier servletEndpointsSupplier) {
44-
return new ServletEndpointRegistrar(properties.getBasePath(),
45-
servletEndpointsSupplier.getEndpoints());
46-
}
47-
4848
@Bean
4949
public ExposeExcludePropertyEndpointFilter<ExposableServletEndpoint> servletExposeExcludePropertyEndpointFilter(
5050
WebEndpointProperties properties) {
@@ -53,4 +53,41 @@ public ExposeExcludePropertyEndpointFilter<ExposableServletEndpoint> servletExpo
5353
exposure.getInclude(), exposure.getExclude());
5454
}
5555

56+
@Configuration
57+
@ConditionalOnClass(DispatcherServlet.class)
58+
public class WebMvcServletEndpointManagementContextConfiguration {
59+
60+
private final ApplicationContext context;
61+
62+
public WebMvcServletEndpointManagementContextConfiguration(ApplicationContext context) {
63+
this.context = context;
64+
}
65+
66+
@Bean
67+
public ServletEndpointRegistrar servletEndpointRegistrar(
68+
WebEndpointProperties properties,
69+
ServletEndpointsSupplier servletEndpointsSupplier) {
70+
DispatcherServletPathProvider servletPathProvider = this.context.getBean(DispatcherServletPathProvider.class);
71+
String servletPath = (servletPathProvider.getServletPath().equals("/") ? "" : servletPathProvider.getServletPath());
72+
return new ServletEndpointRegistrar(servletPath + properties.getBasePath(),
73+
servletEndpointsSupplier.getEndpoints());
74+
}
75+
76+
}
77+
78+
@Configuration
79+
@ConditionalOnClass(ResourceConfig.class)
80+
@ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet")
81+
public class JerseyServletEndpointManagementContextConfiguration {
82+
83+
@Bean
84+
public ServletEndpointRegistrar servletEndpointRegistrar(
85+
WebEndpointProperties properties,
86+
ServletEndpointsSupplier servletEndpointsSupplier) {
87+
return new ServletEndpointRegistrar(properties.getBasePath(),
88+
servletEndpointsSupplier.getEndpoints());
89+
}
90+
91+
}
92+
5693
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfigurationTests.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,29 @@
1818

1919
import java.util.Collections;
2020

21+
import org.glassfish.jersey.server.ResourceConfig;
2122
import org.junit.Test;
2223

2324
import org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar;
2425
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
26+
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPathProvider;
2527
import org.springframework.boot.context.properties.EnableConfigurationProperties;
28+
import org.springframework.boot.test.context.FilteredClassLoader;
2629
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
2730
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
2831
import org.springframework.context.annotation.Bean;
2932
import org.springframework.context.annotation.Configuration;
3033
import org.springframework.context.annotation.Import;
34+
import org.springframework.test.util.ReflectionTestUtils;
35+
import org.springframework.web.servlet.DispatcherServlet;
3136

3237
import static org.assertj.core.api.Assertions.assertThat;
3338

3439
/**
3540
* Tests for {@link ServletEndpointManagementContextConfiguration}.
3641
*
3742
* @author Phillip Webb
43+
* @author Madhura Bhave
3844
*/
3945
public class ServletEndpointManagementContextConfigurationTests {
4046

@@ -43,8 +49,28 @@ public class ServletEndpointManagementContextConfigurationTests {
4349

4450
@Test
4551
public void contextShouldContainServletEndpointRegistrar() {
46-
this.contextRunner.run((context) -> assertThat(context)
47-
.hasSingleBean(ServletEndpointRegistrar.class));
52+
FilteredClassLoader classLoader = new FilteredClassLoader(
53+
ResourceConfig.class);
54+
this.contextRunner.withClassLoader(classLoader).run((context) -> {
55+
assertThat(context)
56+
.hasSingleBean(ServletEndpointRegistrar.class);
57+
ServletEndpointRegistrar bean = context.getBean(ServletEndpointRegistrar.class);
58+
String basePath = (String) ReflectionTestUtils.getField(bean, "basePath");
59+
assertThat(basePath).isEqualTo("/test/actuator");
60+
});
61+
}
62+
63+
@Test
64+
public void servletPathShouldNotAffectJerseyConfiguration() {
65+
FilteredClassLoader classLoader = new FilteredClassLoader(
66+
DispatcherServlet.class);
67+
this.contextRunner.withClassLoader(classLoader).run((context) -> {
68+
assertThat(context)
69+
.hasSingleBean(ServletEndpointRegistrar.class);
70+
ServletEndpointRegistrar bean = context.getBean(ServletEndpointRegistrar.class);
71+
String basePath = (String) ReflectionTestUtils.getField(bean, "basePath");
72+
assertThat(basePath).isEqualTo("/actuator");
73+
});
4874
}
4975

5076
@Test
@@ -64,6 +90,11 @@ public ServletEndpointsSupplier servletEndpointsSupplier() {
6490
return () -> Collections.emptyList();
6591
}
6692

93+
@Bean
94+
public DispatcherServletPathProvider servletPathProvider() {
95+
return () -> "/test";
96+
}
97+
6798
}
6899

69100
}

0 commit comments

Comments
 (0)