Skip to content

Support resolve health groups #16252

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.util.Assert;

Expand All @@ -27,6 +29,7 @@
*
* @author Vedran Pavic
* @author Stephane Nicoll
* @author Eddú Meléndez
* @since 2.1.0
*/
public class DefaultHealthIndicatorRegistry implements HealthIndicatorRegistry {
Expand Down Expand Up @@ -82,6 +85,20 @@ public HealthIndicator get(String name) {
}
}

@Override
public Map<String, HealthIndicator> get(List<String> names) {
Assert.notEmpty(names, "Name must not be empty");
synchronized (this.monitor) {
return names.stream()
.map((name) -> this.healthIndicators.entrySet().stream()
.filter((entry) -> entry.getKey().equals(name))
.collect(Collectors.toMap(Map.Entry::getKey,
Map.Entry::getValue)))
.flatMap((map) -> map.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
}

@Override
public Map<String, HealthIndicator> getAll() {
synchronized (this.monitor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

package org.springframework.boot.actuate.health;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
Expand All @@ -28,6 +32,7 @@
* @author Christian Dupuis
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Eddú Meléndez
* @since 2.0.0
*/
@Endpoint(id = "health")
Expand Down Expand Up @@ -63,6 +68,14 @@ public Health healthForComponent(@Selector String component) {
return (indicator != null) ? indicator.health() : null;
}

@ReadOperation
public Health healthForComponents(@Selector String... components) {
HealthAggregator aggregator = new OrderedHealthAggregator();
Map<String, Health> healths = getNestedHealthIndicators(this.healthIndicator,
components);
return aggregator.aggregate(healths);
}

/**
* Return the {@link Health} of a particular {@code instance} managed by the specified
* {@code component} or {@code null} if that particular component is not a
Expand All @@ -88,4 +101,19 @@ private HealthIndicator getNestedHealthIndicator(HealthIndicator healthIndicator
return null;
}

private Map<String, Health> getNestedHealthIndicators(HealthIndicator healthIndicator,
String... names) {
if (healthIndicator instanceof CompositeHealthIndicator) {
Map<String, HealthIndicator> healthIndicators = ((CompositeHealthIndicator) healthIndicator)
.getRegistry().get(Arrays.asList(names));

Map<String, Health> healths = new LinkedHashMap<>();
for (Map.Entry<String, HealthIndicator> entry : healthIndicators.entrySet()) {
healths.put(entry.getKey(), entry.getValue().health());
}
return healths;
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.springframework.boot.actuate.health;

import java.util.List;
import java.util.Map;

/**
Expand All @@ -26,6 +27,7 @@
* @author Andy Wilkinson
* @author Vedran Pavic
* @author Stephane Nicoll
* @author Eddú Meléndez
* @since 2.1.0
*/
public interface HealthIndicatorRegistry {
Expand Down Expand Up @@ -57,6 +59,8 @@ public interface HealthIndicatorRegistry {
*/
HealthIndicator get(String name);

Map<String, HealthIndicator> get(List<String> names);

/**
* Returns a snapshot of the registered health indicators and their names. The
* contents of the map do not reflect subsequent changes to the registry.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
* @author Christian Dupuis
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Eddú Meléndez
*/
public class HealthEndpointTests {

Expand Down Expand Up @@ -107,6 +108,22 @@ public void statusForComponentInstanceThatIsNotACompositeReturnNull() {
assertThat(health).isNull();
}

@Test
public void callSpecificComponents() {
Map<String, HealthIndicator> healthIndicators = new HashMap<>();
healthIndicators.put("one", one);
healthIndicators.put("two", two);
HealthEndpoint endpoint = new HealthEndpoint(
createHealthIndicator(healthIndicators));
Health health = endpoint.healthForComponents("one", "two");
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails()).containsOnlyKeys("one", "two");
Health upHealth = (Health) health.getDetails().get("one");
assertThat(upHealth.getDetails()).containsOnly(entry("first", "1"));
Health upAgainHealth = (Health) health.getDetails().get("two");
assertThat(upAgainHealth.getDetails()).containsOnly(entry("second", "2"));
}

private HealthIndicator createHealthIndicator(
Map<String, HealthIndicator> healthIndicators) {
return new CompositeHealthIndicator(new OrderedHealthAggregator(),
Expand Down