Properly discover endpoints that are proxied
Previously to this commit, if a `@ControllerEndpoint`, `@RestControllerEndpoint` or `@ServletEndpoint` annotated bean was proxied, the endpoint wasn't properly detected. This commit makes sure that annotation retrieval works on the user class while preserving the get (vs. find) retrieval semantic Closes gh-12441
This commit is contained in:
@@ -29,6 +29,7 @@ import org.springframework.boot.actuate.endpoint.web.PathMapper;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link EndpointDiscoverer} for {@link ExposableControllerEndpoint controller
|
||||
@@ -60,7 +61,7 @@ public class ControllerEndpointDiscoverer
|
||||
|
||||
@Override
|
||||
protected boolean isEndpointExposed(Object endpointBean) {
|
||||
Class<?> type = endpointBean.getClass();
|
||||
Class<?> type = ClassUtils.getUserClass(endpointBean.getClass());
|
||||
return AnnotatedElementUtils.isAnnotated(type, ControllerEndpoint.class)
|
||||
|| AnnotatedElementUtils.isAnnotated(type, RestControllerEndpoint.class);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.boot.actuate.endpoint.web.PathMapper;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link EndpointDiscoverer} for {@link ExposableServletEndpoint servlet endpoints}.
|
||||
@@ -60,7 +61,7 @@ public class ServletEndpointDiscoverer
|
||||
|
||||
@Override
|
||||
protected boolean isEndpointExposed(Object endpointBean) {
|
||||
Class<?> type = endpointBean.getClass();
|
||||
Class<?> type = ClassUtils.getUserClass(endpointBean.getClass());
|
||||
return AnnotatedElementUtils.isAnnotated(type, ServletEndpoint.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,14 @@ import org.springframework.boot.actuate.endpoint.annotation.DiscoveredEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
import org.springframework.boot.actuate.endpoint.web.PathMapper;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -73,6 +76,22 @@ public class ControllerEndpointDiscovererTests {
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEndpointsShouldDiscoverProxyControllerEndpoints() {
|
||||
this.contextRunner.withUserConfiguration(TestProxyControllerEndpoint.class)
|
||||
.withConfiguration(AutoConfigurations.of(
|
||||
ValidationAutoConfiguration.class))
|
||||
.run(assertDiscoverer((discoverer) -> {
|
||||
Collection<ExposableControllerEndpoint> endpoints = discoverer.getEndpoints();
|
||||
assertThat(endpoints).hasSize(1);
|
||||
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
|
||||
assertThat(endpoint.getId()).isEqualTo("testcontroller");
|
||||
assertThat(endpoint.getController())
|
||||
.isInstanceOf(TestProxyControllerEndpoint.class);
|
||||
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEndpointsShouldIncludeRestControllerEndpoints() {
|
||||
this.contextRunner.withUserConfiguration(TestRestControllerEndpoint.class)
|
||||
@@ -86,6 +105,22 @@ public class ControllerEndpointDiscovererTests {
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEndpointsShouldDiscoverProxyRestControllerEndpoints() {
|
||||
this.contextRunner.withUserConfiguration(TestProxyRestControllerEndpoint.class)
|
||||
.withConfiguration(AutoConfigurations.of(
|
||||
ValidationAutoConfiguration.class))
|
||||
.run(assertDiscoverer((discoverer) -> {
|
||||
Collection<ExposableControllerEndpoint> endpoints = discoverer.getEndpoints();
|
||||
assertThat(endpoints).hasSize(1);
|
||||
ExposableControllerEndpoint endpoint = endpoints.iterator().next();
|
||||
assertThat(endpoint.getId()).isEqualTo("testrestcontroller");
|
||||
assertThat(endpoint.getController())
|
||||
.isInstanceOf(TestProxyRestControllerEndpoint.class);
|
||||
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEndpointsShouldNotDiscoverRegularEndpoints() {
|
||||
this.contextRunner.withUserConfiguration(WithRegularEndpointConfiguration.class)
|
||||
@@ -133,11 +168,23 @@ public class ControllerEndpointDiscovererTests {
|
||||
|
||||
}
|
||||
|
||||
@ControllerEndpoint(id = "testcontroller")
|
||||
@Validated
|
||||
static class TestProxyControllerEndpoint {
|
||||
|
||||
}
|
||||
|
||||
@RestControllerEndpoint(id = "testrestcontroller")
|
||||
static class TestRestControllerEndpoint {
|
||||
|
||||
}
|
||||
|
||||
@RestControllerEndpoint(id = "testrestcontroller")
|
||||
@Validated
|
||||
static class TestProxyRestControllerEndpoint {
|
||||
|
||||
}
|
||||
|
||||
@Endpoint(id = "test")
|
||||
static class TestEndpoint {
|
||||
|
||||
|
||||
@@ -40,11 +40,14 @@ import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointServlet;
|
||||
import org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.web.PathMapper;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -81,6 +84,20 @@ public class ServletEndpointDiscovererTests {
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEndpointsShouldDiscoverProxyServletEndpoints() {
|
||||
this.contextRunner.withUserConfiguration(TestProxyServletEndpoint.class)
|
||||
.withConfiguration(AutoConfigurations.of(ValidationAutoConfiguration.class))
|
||||
.run(assertDiscoverer((discoverer) -> {
|
||||
Collection<ExposableServletEndpoint> endpoints = discoverer.getEndpoints();
|
||||
assertThat(endpoints).hasSize(1);
|
||||
ExposableServletEndpoint endpoint = endpoints.iterator().next();
|
||||
assertThat(endpoint.getId()).isEqualTo("testservlet");
|
||||
assertThat(endpoint.getEndpointServlet()).isNotNull();
|
||||
assertThat(endpoint).isInstanceOf(DiscoveredEndpoint.class);
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEndpointsShouldNotDiscoverRegularEndpoints() {
|
||||
this.contextRunner.withUserConfiguration(WithRegularEndpointConfiguration.class)
|
||||
@@ -163,6 +180,17 @@ public class ServletEndpointDiscovererTests {
|
||||
|
||||
}
|
||||
|
||||
@ServletEndpoint(id = "testservlet")
|
||||
@Validated
|
||||
static class TestProxyServletEndpoint implements Supplier<EndpointServlet> {
|
||||
|
||||
@Override
|
||||
public EndpointServlet get() {
|
||||
return new EndpointServlet(TestServlet.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Endpoint(id = "test")
|
||||
static class TestEndpoint {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user