Provide links to all types of endpoints
Previously, links were only provide to web endpoints. This commit expands link resolution to also provide links for servlet endpoints, controller endpoints, and rest controller endpoints. Closes gh-11902
This commit is contained in:
@@ -25,6 +25,7 @@ import org.assertj.core.api.Condition;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.OperationType;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.ExposableControllerEndpoint;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
@@ -37,12 +38,10 @@ import static org.mockito.Mockito.mock;
|
||||
*/
|
||||
public class EndpointLinksResolverTests {
|
||||
|
||||
private final EndpointLinksResolver linksResolver = new EndpointLinksResolver();
|
||||
|
||||
@Test
|
||||
public void linkResolutionWithTrailingSlashStripsSlashOnSelfLink() {
|
||||
Map<String, Link> links = this.linksResolver.resolveLinks(Collections.emptyList(),
|
||||
"https://api.example.com/actuator/");
|
||||
Map<String, Link> links = new EndpointLinksResolver(Collections.emptyList())
|
||||
.resolveLinks("https://api.example.com/actuator/");
|
||||
assertThat(links).hasSize(1);
|
||||
assertThat(links).hasEntrySatisfying("self",
|
||||
linkWithHref("https://api.example.com/actuator"));
|
||||
@@ -50,15 +49,15 @@ public class EndpointLinksResolverTests {
|
||||
|
||||
@Test
|
||||
public void linkResolutionWithoutTrailingSlash() {
|
||||
Map<String, Link> links = this.linksResolver.resolveLinks(Collections.emptyList(),
|
||||
"https://api.example.com/actuator");
|
||||
Map<String, Link> links = new EndpointLinksResolver(Collections.emptyList())
|
||||
.resolveLinks("https://api.example.com/actuator");
|
||||
assertThat(links).hasSize(1);
|
||||
assertThat(links).hasEntrySatisfying("self",
|
||||
linkWithHref("https://api.example.com/actuator"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolvedLinksContainsALinkForEachEndpointOperation() {
|
||||
public void resolvedLinksContainsALinkForEachWebEndpointOperation() {
|
||||
List<WebOperation> operations = new ArrayList<>();
|
||||
operations.add(operationWithPath("/alpha", "alpha"));
|
||||
operations.add(operationWithPath("/alpha/{name}", "alpha-name"));
|
||||
@@ -67,8 +66,8 @@ public class EndpointLinksResolverTests {
|
||||
given(endpoint.isEnableByDefault()).willReturn(true);
|
||||
given(endpoint.getOperations()).willReturn(operations);
|
||||
String requestUrl = "https://api.example.com/actuator";
|
||||
Map<String, Link> links = this.linksResolver
|
||||
.resolveLinks(Collections.singletonList(endpoint), requestUrl);
|
||||
Map<String, Link> links = new EndpointLinksResolver(
|
||||
Collections.singletonList(endpoint)).resolveLinks(requestUrl);
|
||||
assertThat(links).hasSize(3);
|
||||
assertThat(links).hasEntrySatisfying("self",
|
||||
linkWithHref("https://api.example.com/actuator"));
|
||||
@@ -78,6 +77,39 @@ public class EndpointLinksResolverTests {
|
||||
linkWithHref("https://api.example.com/actuator/alpha/{name}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolvedLinksContainsALinkForServletEndpoint() {
|
||||
ExposableServletEndpoint servletEndpoint = mock(ExposableServletEndpoint.class);
|
||||
given(servletEndpoint.getId()).willReturn("alpha");
|
||||
given(servletEndpoint.isEnableByDefault()).willReturn(true);
|
||||
given(servletEndpoint.getRootPath()).willReturn("alpha");
|
||||
String requestUrl = "https://api.example.com/actuator";
|
||||
Map<String, Link> links = new EndpointLinksResolver(
|
||||
Collections.singletonList(servletEndpoint)).resolveLinks(requestUrl);
|
||||
assertThat(links).hasSize(2);
|
||||
assertThat(links).hasEntrySatisfying("self",
|
||||
linkWithHref("https://api.example.com/actuator"));
|
||||
assertThat(links).hasEntrySatisfying("alpha",
|
||||
linkWithHref("https://api.example.com/actuator/alpha"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolvedLinksContainsALinkForControllerEndpoint() {
|
||||
ExposableControllerEndpoint controllerEndpoint = mock(
|
||||
ExposableControllerEndpoint.class);
|
||||
given(controllerEndpoint.getId()).willReturn("alpha");
|
||||
given(controllerEndpoint.isEnableByDefault()).willReturn(true);
|
||||
given(controllerEndpoint.getRootPath()).willReturn("alpha");
|
||||
String requestUrl = "https://api.example.com/actuator";
|
||||
Map<String, Link> links = new EndpointLinksResolver(
|
||||
Collections.singletonList(controllerEndpoint)).resolveLinks(requestUrl);
|
||||
assertThat(links).hasSize(2);
|
||||
assertThat(links).hasEntrySatisfying("self",
|
||||
linkWithHref("https://api.example.com/actuator"));
|
||||
assertThat(links).hasEntrySatisfying("alpha",
|
||||
linkWithHref("https://api.example.com/actuator/alpha"));
|
||||
}
|
||||
|
||||
private WebOperation operationWithPath(String path, String id) {
|
||||
WebOperationRequestPredicate predicate = new WebOperationRequestPredicate(path,
|
||||
WebEndpointHttpMethod.GET, Collections.emptyList(),
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
import org.glassfish.jersey.servlet.ServletContainer;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.AbstractWebEndpointIntegrationTests;
|
||||
@@ -110,7 +111,8 @@ public class JerseyWebEndpointIntegrationTests extends
|
||||
Collection<Resource> resources = new JerseyEndpointResourceFactory()
|
||||
.createEndpointResources(
|
||||
new EndpointMapping(environment.getProperty("endpointPath")),
|
||||
endpointDiscoverer.getEndpoints(), endpointMediaTypes);
|
||||
endpointDiscoverer.getEndpoints(), endpointMediaTypes,
|
||||
new EndpointLinksResolver(endpointDiscoverer.getEndpoints()));
|
||||
resourceConfig.registerResources(new HashSet<>(resources));
|
||||
resourceConfig.register(JacksonFeature.class);
|
||||
resourceConfig.register(new ObjectMapperContextResolver(new ObjectMapper()),
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.Arrays;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.AbstractWebEndpointIntegrationTests;
|
||||
@@ -132,7 +133,8 @@ public class WebFluxEndpointIntegrationTests
|
||||
return new WebFluxEndpointHandlerMapping(
|
||||
new EndpointMapping(environment.getProperty("endpointPath")),
|
||||
endpointDiscoverer.getEndpoints(), endpointMediaTypes,
|
||||
corsConfiguration);
|
||||
corsConfiguration,
|
||||
new EndpointLinksResolver(endpointDiscoverer.getEndpoints()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.AbstractWebEndpointIntegrationTests;
|
||||
@@ -129,7 +130,8 @@ public class MvcWebEndpointIntegrationTests extends
|
||||
return new WebMvcEndpointHandlerMapping(
|
||||
new EndpointMapping(environment.getProperty("endpointPath")),
|
||||
endpointDiscoverer.getEndpoints(), endpointMediaTypes,
|
||||
corsConfiguration);
|
||||
corsConfiguration,
|
||||
new EndpointLinksResolver(endpointDiscoverer.getEndpoints()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.junit.runners.model.InitializationError;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
|
||||
import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.PathMapper;
|
||||
@@ -104,7 +105,8 @@ class JerseyEndpointsRunner extends AbstractWebEndpointRunner {
|
||||
Collections.emptyList(), Collections.emptyList());
|
||||
Collection<Resource> resources = new JerseyEndpointResourceFactory()
|
||||
.createEndpointResources(new EndpointMapping("/actuator"),
|
||||
discoverer.getEndpoints(), endpointMediaTypes);
|
||||
discoverer.getEndpoints(), endpointMediaTypes,
|
||||
new EndpointLinksResolver(discoverer.getEndpoints()));
|
||||
config.registerResources(new HashSet<>(resources));
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.junit.runners.model.InitializationError;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
|
||||
import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.PathMapper;
|
||||
@@ -110,7 +111,8 @@ class WebFluxEndpointsRunner extends AbstractWebEndpointRunner {
|
||||
Collections.emptyList(), Collections.emptyList());
|
||||
return new WebFluxEndpointHandlerMapping(new EndpointMapping("/actuator"),
|
||||
discoverer.getEndpoints(), endpointMediaTypes,
|
||||
new CorsConfiguration());
|
||||
new CorsConfiguration(),
|
||||
new EndpointLinksResolver(discoverer.getEndpoints()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.junit.runners.model.InitializationError;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
|
||||
import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.PathMapper;
|
||||
@@ -93,7 +94,8 @@ class WebMvcEndpointRunner extends AbstractWebEndpointRunner {
|
||||
Collections.emptyList(), Collections.emptyList());
|
||||
return new WebMvcEndpointHandlerMapping(new EndpointMapping("/actuator"),
|
||||
discoverer.getEndpoints(), endpointMediaTypes,
|
||||
new CorsConfiguration());
|
||||
new CorsConfiguration(),
|
||||
new EndpointLinksResolver(discoverer.getEndpoints()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user