mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-15 01:07:30 +08:00
Support multiple health groups with an additional path with Jersey
This commit knowingly makes breaking API changes to JerseyHealthEndpointAdditionalPathResourceFactory. We considered other options but they all had the potential to be backwards incompatible in one way or another. Faced with that situation we concluded that the likelihood of anyone using the modified API directly is small enough to warrant making the breaking changes. If it becomes apparent that we have misjudged things we can revisit the changes in the future. Closes gh-36250
This commit is contained in:
parent
76cd102aa6
commit
52f732920b
@ -184,7 +184,7 @@ class JerseyWebEndpointManagementContextConfiguration {
|
||||
JerseyHealthEndpointAdditionalPathResourceFactory resourceFactory = new JerseyHealthEndpointAdditionalPathResourceFactory(
|
||||
WebServerNamespace.MANAGEMENT, this.groups);
|
||||
Collection<Resource> endpointResources = resourceFactory
|
||||
.createEndpointResources(mapping, Collections.singletonList(this.endpoint), null, null, false)
|
||||
.createEndpointResources(mapping, Collections.singletonList(this.endpoint))
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
|
@ -163,7 +163,7 @@ class HealthEndpointWebExtensionConfiguration {
|
||||
JerseyHealthEndpointAdditionalPathResourceFactory resourceFactory = new JerseyHealthEndpointAdditionalPathResourceFactory(
|
||||
WebServerNamespace.SERVER, this.groups);
|
||||
Collection<Resource> endpointResources = resourceFactory
|
||||
.createEndpointResources(mapping, Collections.singletonList(this.endpoint), null, null, false)
|
||||
.createEndpointResources(mapping, Collections.singletonList(this.endpoint))
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
|
@ -27,6 +27,8 @@ import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatNoException;
|
||||
|
||||
/**
|
||||
* Abstract base class for health groups with an additional path.
|
||||
*
|
||||
@ -52,6 +54,18 @@ abstract class AbstractHealthEndpointAdditionalPathIntegrationTests<T extends Ab
|
||||
.run(withWebTestClient(this::testResponse, "local.server.port"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleGroupsAreAvailableAtAdditionalPaths() {
|
||||
this.runner
|
||||
.withPropertyValues("management.endpoint.health.group.one.include=diskSpace",
|
||||
"management.endpoint.health.group.two.include=diskSpace",
|
||||
"management.endpoint.health.group.one.additional-path=server:/alpha",
|
||||
"management.endpoint.health.group.two.additional-path=server:/bravo",
|
||||
"management.endpoint.health.group.one.show-components=always",
|
||||
"management.endpoint.health.group.two.show-components=always")
|
||||
.run(withWebTestClient((client) -> testResponses(client, "/alpha", "/bravo"), "local.server.port"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void groupIsAvailableAtAdditionalPathWithoutSlash() {
|
||||
this.runner
|
||||
@ -125,17 +139,24 @@ abstract class AbstractHealthEndpointAdditionalPathIntegrationTests<T extends Ab
|
||||
}
|
||||
|
||||
private void testResponse(WebTestClient client) {
|
||||
client.get()
|
||||
.uri("/healthz")
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody()
|
||||
.jsonPath("status")
|
||||
.isEqualTo("UP")
|
||||
.jsonPath("components.diskSpace")
|
||||
.exists();
|
||||
testResponses(client, "/healthz");
|
||||
}
|
||||
|
||||
private void testResponses(WebTestClient client, String... paths) {
|
||||
for (String path : paths) {
|
||||
assertThatNoException().as(path)
|
||||
.isThrownBy(() -> client.get()
|
||||
.uri(path)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody()
|
||||
.jsonPath("status")
|
||||
.isEqualTo("UP")
|
||||
.jsonPath("components.diskSpace")
|
||||
.exists());
|
||||
}
|
||||
}
|
||||
|
||||
private ContextConsumer<A> withWebTestClient(Consumer<WebTestClient> consumer, String property) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,11 +16,17 @@
|
||||
|
||||
package org.springframework.boot.actuate.endpoint.web.jersey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebOperation;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebServerNamespace;
|
||||
@ -35,7 +41,9 @@ import org.springframework.boot.actuate.health.HealthEndpointGroups;
|
||||
* @author Madhura Bhave
|
||||
* @since 2.6.0
|
||||
*/
|
||||
public class JerseyHealthEndpointAdditionalPathResourceFactory extends JerseyEndpointResourceFactory {
|
||||
public final class JerseyHealthEndpointAdditionalPathResourceFactory {
|
||||
|
||||
private final JerseyEndpointResourceFactory delegate = new JerseyEndpointResourceFactory();
|
||||
|
||||
private final Set<HealthEndpointGroup> groups;
|
||||
|
||||
@ -47,20 +55,30 @@ public class JerseyHealthEndpointAdditionalPathResourceFactory extends JerseyEnd
|
||||
this.groups = groups.getAllWithAdditionalPath(serverNamespace);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Resource createResource(EndpointMapping endpointMapping, WebOperation operation) {
|
||||
public Collection<Resource> createEndpointResources(EndpointMapping endpointMapping,
|
||||
Collection<ExposableWebEndpoint> endpoints) {
|
||||
return endpoints.stream()
|
||||
.flatMap((endpoint) -> endpoint.getOperations().stream())
|
||||
.flatMap((operation) -> createResources(endpointMapping, operation))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private Stream<Resource> createResources(EndpointMapping endpointMapping, WebOperation operation) {
|
||||
WebOperationRequestPredicate requestPredicate = operation.getRequestPredicate();
|
||||
String matchAllRemainingPathSegmentsVariable = requestPredicate.getMatchAllRemainingPathSegmentsVariable();
|
||||
if (matchAllRemainingPathSegmentsVariable != null) {
|
||||
List<Resource> resources = new ArrayList<>();
|
||||
for (HealthEndpointGroup group : this.groups) {
|
||||
AdditionalHealthEndpointPath additionalPath = group.getAdditionalPath();
|
||||
if (additionalPath != null) {
|
||||
return getResource(endpointMapping, operation, requestPredicate, additionalPath.getValue(),
|
||||
this.serverNamespace, (data, pathSegmentsVariable) -> data.getUriInfo().getPath());
|
||||
resources.add(this.delegate.getResource(endpointMapping, operation, requestPredicate,
|
||||
additionalPath.getValue(), this.serverNamespace,
|
||||
(data, pathSegmentsVariable) -> data.getUriInfo().getPath()));
|
||||
}
|
||||
}
|
||||
return resources.stream();
|
||||
}
|
||||
return null;
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user