Merge pull request #780 from tjf/1.0.x
* pull780: Add multi-datasource health indicator support Add CompositeHealthIndicator
This commit is contained in:
commit
2b715b2c86
|
|
@ -38,6 +38,7 @@ import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.TraceEndpoint;
|
import org.springframework.boot.actuate.endpoint.TraceEndpoint;
|
||||||
import org.springframework.boot.actuate.endpoint.VanillaPublicMetrics;
|
import org.springframework.boot.actuate.endpoint.VanillaPublicMetrics;
|
||||||
|
import org.springframework.boot.actuate.health.CompositeHealthIndicator;
|
||||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||||
import org.springframework.boot.actuate.health.SimpleHealthIndicator;
|
import org.springframework.boot.actuate.health.SimpleHealthIndicator;
|
||||||
import org.springframework.boot.actuate.health.VanillaHealthIndicator;
|
import org.springframework.boot.actuate.health.VanillaHealthIndicator;
|
||||||
|
|
@ -75,7 +76,7 @@ public class EndpointAutoConfiguration {
|
||||||
private HealthIndicator<? extends Object> healthIndicator;
|
private HealthIndicator<? extends Object> healthIndicator;
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private DataSource dataSource;
|
private Map<String, DataSource> dataSources;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private InfoPropertiesConfiguration properties;
|
private InfoPropertiesConfiguration properties;
|
||||||
|
|
@ -97,20 +98,30 @@ public class EndpointAutoConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public HealthEndpoint<Object> healthEndpoint() {
|
public HealthEndpoint<?> healthEndpoint() {
|
||||||
if (this.healthIndicator == null) {
|
if (this.healthIndicator == null) {
|
||||||
if (this.dataSource == null) {
|
this.healthIndicator = createHealthIndicator();
|
||||||
this.healthIndicator = new VanillaHealthIndicator();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SimpleHealthIndicator healthIndicator = new SimpleHealthIndicator();
|
|
||||||
healthIndicator.setDataSource(this.dataSource);
|
|
||||||
this.healthIndicator = healthIndicator;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return new HealthEndpoint<Object>(this.healthIndicator);
|
return new HealthEndpoint<Object>(this.healthIndicator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HealthIndicator<? extends Object> createHealthIndicator() {
|
||||||
|
if (this.dataSources == null || this.dataSources.isEmpty()) {
|
||||||
|
return new VanillaHealthIndicator();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.dataSources.size() == 1) {
|
||||||
|
return new SimpleHealthIndicator(this.dataSources.values().iterator().next());
|
||||||
|
}
|
||||||
|
|
||||||
|
CompositeHealthIndicator composite = new CompositeHealthIndicator();
|
||||||
|
for (Map.Entry<String, DataSource> entry : this.dataSources.entrySet()) {
|
||||||
|
composite.addHealthIndicator(entry.getKey(),
|
||||||
|
new SimpleHealthIndicator(entry.getValue()));
|
||||||
|
}
|
||||||
|
return composite;
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public BeansEndpoint beansEndpoint() {
|
public BeansEndpoint beansEndpoint() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2014 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
|
||||||
|
*
|
||||||
|
* http://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.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link HealthIndicator} that returns health indications from all registered delegates.
|
||||||
|
*
|
||||||
|
* @author Tyler J. Frederick
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public class CompositeHealthIndicator implements HealthIndicator<Map<String, Object>> {
|
||||||
|
|
||||||
|
private final Map<String, HealthIndicator<?>> indicators;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link CompositeHealthIndicator}.
|
||||||
|
*/
|
||||||
|
public CompositeHealthIndicator() {
|
||||||
|
this.indicators = new LinkedHashMap<String, HealthIndicator<?>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link CompositeHealthIndicator} from the specified indicators.
|
||||||
|
* @param indicators a map of {@link HealthIndicator}s with the key being used as an
|
||||||
|
* indicator name.
|
||||||
|
*/
|
||||||
|
public CompositeHealthIndicator(Map<String, HealthIndicator<?>> indicators) {
|
||||||
|
this.indicators = new LinkedHashMap<String, HealthIndicator<?>>(indicators);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHealthIndicator(String name, HealthIndicator<?> indicator) {
|
||||||
|
this.indicators.put(name, indicator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> health() {
|
||||||
|
Map<String, Object> health = new LinkedHashMap<String, Object>();
|
||||||
|
for (Map.Entry<String, HealthIndicator<?>> entry : this.indicators.entrySet()) {
|
||||||
|
health.put(entry.getKey(), entry.getValue().health());
|
||||||
|
}
|
||||||
|
return health;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -54,6 +54,21 @@ public class SimpleHealthIndicator implements HealthIndicator<Map<String, Object
|
||||||
|
|
||||||
private String query = null;
|
private String query = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link SimpleHealthIndicator} instance.
|
||||||
|
*/
|
||||||
|
public SimpleHealthIndicator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link SimpleHealthIndicator} using the specified datasource.
|
||||||
|
* @param dataSource the data source
|
||||||
|
*/
|
||||||
|
public SimpleHealthIndicator(DataSource dataSource) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> health() {
|
public Map<String, Object> health() {
|
||||||
LinkedHashMap<String, Object> health = new LinkedHashMap<String, Object>();
|
LinkedHashMap<String, Object> health = new LinkedHashMap<String, Object>();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2014 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
|
||||||
|
*
|
||||||
|
* http://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.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.hasEntry;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link CompositeHealthIndicator}
|
||||||
|
*
|
||||||
|
* @author Tyler J. Frederick
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public class CompositeHealthIndicatorTests {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private HealthIndicator<String> one;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private HealthIndicator<String> two;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private HealthIndicator<String> three;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
given(this.one.health()).willReturn("1");
|
||||||
|
given(this.two.health()).willReturn("2");
|
||||||
|
given(this.three.health()).willReturn("3");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWithIndicators() throws Exception {
|
||||||
|
Map<String, HealthIndicator<?>> indicators = new HashMap<String, HealthIndicator<?>>();
|
||||||
|
indicators.put("one", this.one);
|
||||||
|
indicators.put("two", this.two);
|
||||||
|
CompositeHealthIndicator composite = new CompositeHealthIndicator(indicators);
|
||||||
|
Map<String, Object> result = composite.health();
|
||||||
|
assertThat(result.size(), equalTo(2));
|
||||||
|
assertThat(result, hasEntry("one", (Object) "1"));
|
||||||
|
assertThat(result, hasEntry("two", (Object) "2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWithIndicatorsAndAdd() throws Exception {
|
||||||
|
Map<String, HealthIndicator<?>> indicators = new HashMap<String, HealthIndicator<?>>();
|
||||||
|
indicators.put("one", this.one);
|
||||||
|
indicators.put("two", this.two);
|
||||||
|
CompositeHealthIndicator composite = new CompositeHealthIndicator(indicators);
|
||||||
|
composite.addHealthIndicator("three", this.three);
|
||||||
|
Map<String, Object> result = composite.health();
|
||||||
|
assertThat(result.size(), equalTo(3));
|
||||||
|
assertThat(result, hasEntry("one", (Object) "1"));
|
||||||
|
assertThat(result, hasEntry("two", (Object) "2"));
|
||||||
|
assertThat(result, hasEntry("three", (Object) "3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWithoutAndAdd() throws Exception {
|
||||||
|
CompositeHealthIndicator composite = new CompositeHealthIndicator();
|
||||||
|
composite.addHealthIndicator("one", this.one);
|
||||||
|
composite.addHealthIndicator("two", this.two);
|
||||||
|
Map<String, Object> result = composite.health();
|
||||||
|
assertThat(result.size(), equalTo(2));
|
||||||
|
assertThat(result, hasEntry("one", (Object) "1"));
|
||||||
|
assertThat(result, hasEntry("two", (Object) "2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue