Skip to content

Commit

Permalink
Hacking
Browse files Browse the repository at this point in the history
  • Loading branch information
snicoll committed Apr 28, 2019
1 parent 9cde736 commit a9a57e5
Show file tree
Hide file tree
Showing 10 changed files with 219 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ class HealthEndpointWebExtensionConfiguration {
@Bean
@ConditionalOnMissingBean
public HealthStatusHttpMapper createHealthStatusHttpMapper(
HealthIndicatorProperties healthIndicatorProperties) {
HealthIndicatorProperties properties) {
HealthStatusHttpMapper statusHttpMapper = new HealthStatusHttpMapper();
if (healthIndicatorProperties.getHttpMapping() != null) {
statusHttpMapper.addStatusMapping(healthIndicatorProperties.getHttpMapping());
if (properties.getStatus().getHttpMapping() != null) {
statusHttpMapper.addStatusMapping(properties.getStatus().getHttpMapping());
}
return statusHttpMapper;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@

package org.springframework.boot.actuate.autoconfigure.health;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;

import reactor.core.publisher.Flux;

import org.springframework.boot.actuate.health.ApplicationHealthIndicator;
import org.springframework.boot.actuate.health.DefaultGroupHealthIndicator;
import org.springframework.boot.actuate.health.DefaultGroupReactiveHealthIndicator;
import org.springframework.boot.actuate.health.HealthAggregator;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.HealthIndicatorRegistry;
Expand Down Expand Up @@ -60,17 +64,24 @@ public ApplicationHealthIndicator applicationHealthIndicator() {
public OrderedHealthAggregator healthAggregator(
HealthIndicatorProperties properties) {
OrderedHealthAggregator healthAggregator = new OrderedHealthAggregator();
if (properties.getOrder() != null) {
healthAggregator.setStatusOrder(properties.getOrder());
if (properties.getStatus().getOrder() != null) {
healthAggregator.setStatusOrder(properties.getStatus().getOrder());
}
return healthAggregator;
}

@Bean
@ConditionalOnMissingBean(HealthIndicatorRegistry.class)
public HealthIndicatorRegistry healthIndicatorRegistry(
HealthIndicatorProperties properties, HealthAggregator healthAggregator,
ApplicationContext applicationContext) {
return HealthIndicatorRegistryBeans.get(applicationContext);
HealthIndicatorRegistry registry = HealthIndicatorRegistryBeans
.get(applicationContext);
extractGroups(properties, registry::get).forEach(
(groupName, groupHealthIndicators) -> registry.register(groupName,
new DefaultGroupHealthIndicator(healthAggregator,
groupHealthIndicators)));
return registry;
}

@Configuration(proxyBeanMethods = false)
Expand All @@ -80,13 +91,41 @@ static class ReactiveHealthIndicatorConfiguration {
@Bean
@ConditionalOnMissingBean
public ReactiveHealthIndicatorRegistry reactiveHealthIndicatorRegistry(
HealthIndicatorProperties properties, HealthAggregator healthAggregator,
Map<String, ReactiveHealthIndicator> reactiveHealthIndicators,
Map<String, HealthIndicator> healthIndicators) {
return new ReactiveHealthIndicatorRegistryFactory()
ReactiveHealthIndicatorRegistry registry = new ReactiveHealthIndicatorRegistryFactory()
.createReactiveHealthIndicatorRegistry(reactiveHealthIndicators,
healthIndicators);
extractGroups(properties, registry::get).forEach(
(groupName, groupHealthIndicators) -> registry.register(groupName,
new DefaultGroupReactiveHealthIndicator(healthAggregator,
groupHealthIndicators)));
return registry;
}

}

private static <T> Map<String, Map<String, T>> extractGroups(
HealthIndicatorProperties properties,
Function<String, T> healthIndicatorByName) {
Map<String, Map<String, T>> groupDefinitions = new LinkedHashMap<>();
properties.getGroups().forEach((groupName, indicatorNames) -> {
if (healthIndicatorByName.apply(groupName) != null) {
throw new IllegalArgumentException(
"Could not register health indicator group named '" + groupName
+ "', an health indicator with that name is already registered");
}
Map<String, T> groupHealthIndicators = new LinkedHashMap<>();
indicatorNames.forEach((name) -> {
T healthIndicator = healthIndicatorByName.apply(name);
if (healthIndicator != null) {
groupHealthIndicators.put(name, healthIndicator);
}
});
groupDefinitions.put(groupName, groupHealthIndicators);
});
return groupDefinitions;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,32 +28,52 @@
* @author Christian Dupuis
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "management.health.status")
@ConfigurationProperties(prefix = "management.health")
public class HealthIndicatorProperties {

/**
* Comma-separated list of health statuses in order of severity.
* Health indicator groups. Each entry maps the name of a group with a list of health
* indicators to associate with the group.
*/
private List<String> order = null;
private final Map<String, List<String>> groups = new HashMap<>();

/**
* Mapping of health statuses to HTTP status codes. By default, registered health
* statuses map to sensible defaults (for example, UP maps to 200).
*/
private final Map<String, Integer> httpMapping = new HashMap<>();
private final Status status = new Status();

public List<String> getOrder() {
return this.order;
public Map<String, List<String>> getGroups() {
return this.groups;
}

public void setOrder(List<String> statusOrder) {
if (statusOrder != null && !statusOrder.isEmpty()) {
this.order = statusOrder;
}
public Status getStatus() {
return this.status;
}

public Map<String, Integer> getHttpMapping() {
return this.httpMapping;
public static class Status {

/**
* Comma-separated list of health statuses in order of severity.
*/
private List<String> order = null;

/**
* Mapping of health statuses to HTTP status codes. By default, registered health
* statuses map to sensible defaults (for example, UP maps to 200).
*/
private final Map<String, Integer> httpMapping = new HashMap<>();

public List<String> getOrder() {
return this.order;
}

public void setOrder(List<String> statusOrder) {
if (statusOrder != null && !statusOrder.isEmpty()) {
this.order = statusOrder;
}
}

public Map<String, Integer> getHttpMapping() {
return this.httpMapping;
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2012-2019 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.boot.actuate.health;

import java.util.Map;

/**
* @author Stephane Nicoll
*/
public class DefaultGroupHealthIndicator extends CompositeHealthIndicator
implements GroupHealthIndicator {

public DefaultGroupHealthIndicator(HealthAggregator healthAggregator,
Map<String, HealthIndicator> indicators) {
super(healthAggregator, indicators);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2012-2019 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.boot.actuate.health;

import java.util.Map;

/**
* @author Stephane Nicoll
*/
public class DefaultGroupReactiveHealthIndicator extends CompositeReactiveHealthIndicator
implements GroupReactiveHealthIndicator {

public DefaultGroupReactiveHealthIndicator(HealthAggregator healthAggregator,
Map<String, ReactiveHealthIndicator> healthIndicators) {
super(healthAggregator,
new DefaultReactiveHealthIndicatorRegistry(healthIndicators));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,13 @@ public HealthIndicator get(String name) {
@Override
public Map<String, HealthIndicator> getAll() {
synchronized (this.monitor) {
return Collections
.unmodifiableMap(new LinkedHashMap<>(this.healthIndicators));
Map<String, HealthIndicator> allIndicators = new LinkedHashMap<>();
this.healthIndicators.forEach((name, indicator) -> {
if (!(indicator instanceof GroupHealthIndicator)) {
allIndicators.put(name, indicator);
}
});
return Collections.unmodifiableMap(allIndicators);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,13 @@ public ReactiveHealthIndicator get(String name) {
@Override
public Map<String, ReactiveHealthIndicator> getAll() {
synchronized (this.monitor) {
return Collections
.unmodifiableMap(new LinkedHashMap<>(this.healthIndicators));
Map<String, ReactiveHealthIndicator> allIndicators = new LinkedHashMap<>();
this.healthIndicators.forEach((name, indicator) -> {
if (!(indicator instanceof GroupReactiveHealthIndicator)) {
allIndicators.put(name, indicator);
}
});
return Collections.unmodifiableMap(allIndicators);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2012-2019 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.boot.actuate.health;

/**
* @author Stephane Nicoll
* @since 2.2.0
*/
public interface GroupHealthIndicator extends HealthIndicator {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2012-2019 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.boot.actuate.health;

/**
*
* @author Stephane Nicoll
*/
public interface GroupReactiveHealthIndicator extends ReactiveHealthIndicator {
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,12 @@ spring.jmx.enabled=true
spring.jackson.serialization.write_dates_as_timestamps=false

management.trace.http.include=request-headers,response-headers,principal,remote-address,session-id


management.health.groups.ready=diskSpace
management.health.groups.live=example,hello,db,unknown




management.endpoint.health.show-details=always

0 comments on commit a9a57e5

Please sign in to comment.