From 127328a83366b6bb3d88721eae757e171a694445 Mon Sep 17 00:00:00 2001 From: Christian Dupuis Date: Thu, 8 May 2014 12:37:37 +0200 Subject: [PATCH] Rework HealthEndpoint and HealthIndicators Refactored HealthEndpoint to be able to take multiple HealthIndicators. Extracted configuration of HealthIndicators out of EndpointAutoConfiguration and added new HealthIndicatorAutoConfiguration class. Added HealthIndicators for Redis and Mongo. --- spring-boot-actuator/pom.xml | 5 + .../EndpointAutoConfiguration.java | 39 +---- .../HealthIndicatorAutoConfiguration.java | 137 ++++++++++++++++++ .../boot/actuate/endpoint/HealthEndpoint.java | 41 ++++-- .../actuate/health/MongoHealthIndicator.java | 57 ++++++++ .../actuate/health/RedisHealthIndicator.java | 63 ++++++++ .../main/resources/META-INF/spring.factories | 1 + .../EndpointAutoConfigurationTests.java | 29 +++- ...HealthIndicatorAutoConfigurationTests.java | 127 ++++++++++++++++ .../actuate/endpoint/HealthEndpointTests.java | 25 +++- .../health/MongoHealthIndicatorTests.java | 63 ++++++++ .../health/RedisHealthIndicatorTests.java | 62 ++++++++ 12 files changed, 588 insertions(+), 61 deletions(-) create mode 100644 spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfiguration.java create mode 100644 spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/MongoHealthIndicator.java create mode 100644 spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/RedisHealthIndicator.java create mode 100644 spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfigurationTests.java create mode 100644 spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/MongoHealthIndicatorTests.java create mode 100644 spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/RedisHealthIndicatorTests.java diff --git a/spring-boot-actuator/pom.xml b/spring-boot-actuator/pom.xml index 37338e0b8bd..1ecb5e8bc6b 100644 --- a/spring-boot-actuator/pom.xml +++ b/spring-boot-actuator/pom.xml @@ -76,6 +76,11 @@ spring-data-redis true + + org.springframework.data + spring-data-mongodb + true + org.springframework.security spring-security-web diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfiguration.java index c06da53e273..5d588c7db75 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfiguration.java @@ -20,8 +20,6 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; -import javax.sql.DataSource; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.actuate.endpoint.AutoConfigurationReportEndpoint; @@ -38,10 +36,6 @@ import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint; import org.springframework.boot.actuate.endpoint.ShutdownEndpoint; import org.springframework.boot.actuate.endpoint.TraceEndpoint; 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.SimpleHealthIndicator; -import org.springframework.boot.actuate.health.VanillaHealthIndicator; import org.springframework.boot.actuate.metrics.reader.MetricReader; import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository; import org.springframework.boot.actuate.trace.InMemoryTraceRepository; @@ -64,20 +58,15 @@ import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping; /** * {@link EnableAutoConfiguration Auto-configuration} for common management * {@link Endpoint}s. - * + * * @author Dave Syer * @author Phillip Webb * @author Greg Turnquist + * @author Chiristian Dupuis */ @Configuration public class EndpointAutoConfiguration { - @Autowired(required = false) - private HealthIndicator healthIndicator; - - @Autowired(required = false) - private Map dataSources; - @Autowired private InfoPropertiesConfiguration properties; @@ -98,28 +87,8 @@ public class EndpointAutoConfiguration { @Bean @ConditionalOnMissingBean - public HealthEndpoint healthEndpoint() { - if (this.healthIndicator == null) { - this.healthIndicator = createHealthIndicator(); - } - return new HealthEndpoint(this.healthIndicator); - } - - private HealthIndicator 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 entry : this.dataSources.entrySet()) { - composite.addHealthIndicator(entry.getKey(), - new SimpleHealthIndicator(entry.getValue())); - } - return composite; + public HealthEndpoint healthEndpoint() { + return new HealthEndpoint(); } @Bean diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfiguration.java new file mode 100644 index 00000000000..9cca3915bdf --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfiguration.java @@ -0,0 +1,137 @@ +/* + * Copyright 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.autoconfigure; + +import java.util.Map; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.health.CompositeHealthIndicator; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.actuate.health.MongoHealthIndicator; +import org.springframework.boot.actuate.health.RedisHealthIndicator; +import org.springframework.boot.actuate.health.SimpleHealthIndicator; +import org.springframework.boot.actuate.health.VanillaHealthIndicator; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.jdbc.CommonsDataSourceConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; +import org.springframework.boot.autoconfigure.jdbc.HikariDataSourceConfiguration; +import org.springframework.boot.autoconfigure.jdbc.TomcatDataSourceConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration; +import org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.redis.connection.RedisConnectionFactory; + +/** + * @author Christian Dupuis + * @since 1.1.0 + */ +@Configuration +@AutoConfigureAfter({ DataSourceAutoConfiguration.class, + EmbeddedDataSourceConfiguration.class, CommonsDataSourceConfiguration.class, + HikariDataSourceConfiguration.class, TomcatDataSourceConfiguration.class, + MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, + RedisAutoConfiguration.class }) +public class HealthIndicatorAutoConfiguration { + + @Bean + @ConditionalOnMissingBean(HealthIndicator.class) + public HealthIndicator statusHealthIndicator() { + return new VanillaHealthIndicator(); + } + + @Configuration + @ConditionalOnBean(DataSource.class) + public static class DataSourcesHealthIndicatorConfiguration { + + @Autowired(required = false) + private Map dataSources; + + @Bean + @ConditionalOnMissingBean(name = "dbHealthIndicator") + public HealthIndicator dbHealthIndicator() { + if (this.dataSources.size() == 1) { + return new SimpleHealthIndicator(this.dataSources.values().iterator() + .next()); + } + + CompositeHealthIndicator composite = new CompositeHealthIndicator(); + for (Map.Entry entry : this.dataSources.entrySet()) { + composite.addHealthIndicator(entry.getKey(), new SimpleHealthIndicator( + entry.getValue())); + } + return composite; + } + } + + @Configuration + @ConditionalOnBean(MongoTemplate.class) + public static class MongoHealthIndicatorConfiguration { + + @Autowired + private Map mongoTemplates; + + @Bean + @ConditionalOnMissingBean(name = "mongoHealthIndicator") + public HealthIndicator mongoHealthIndicator() { + if (this.mongoTemplates.size() == 1) { + return new MongoHealthIndicator(this.mongoTemplates.values().iterator() + .next()); + } + + CompositeHealthIndicator composite = new CompositeHealthIndicator(); + for (Map.Entry entry : this.mongoTemplates.entrySet()) { + composite.addHealthIndicator(entry.getKey(), new MongoHealthIndicator( + entry.getValue())); + } + return composite; + } + } + + @Configuration + @ConditionalOnBean(RedisConnectionFactory.class) + public static class RedisHealthIndicatorConfiguration { + + @Autowired + private Map redisConnectionFactories; + + @Bean + @ConditionalOnMissingBean(name = "redisHealthIndicator") + public HealthIndicator redisHealthIndicator() { + if (this.redisConnectionFactories.size() == 1) { + return new RedisHealthIndicator(this.redisConnectionFactories.values() + .iterator().next()); + } + + CompositeHealthIndicator composite = new CompositeHealthIndicator(); + for (Map.Entry entry : this.redisConnectionFactories + .entrySet()) { + composite.addHealthIndicator(entry.getKey(), new RedisHealthIndicator( + entry.getValue())); + } + return composite; + } + } + +} diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/HealthEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/HealthEndpoint.java index 51bbcef8b20..b680cfb01b7 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/HealthEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/HealthEndpoint.java @@ -16,34 +16,53 @@ package org.springframework.boot.actuate.endpoint; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.util.Assert; /** * {@link Endpoint} to expose application health. - * + * * @author Dave Syer + * @author Christian Dupuis */ @ConfigurationProperties(prefix = "endpoints.health", ignoreUnknownFields = false) -public class HealthEndpoint extends AbstractEndpoint { +public class HealthEndpoint extends AbstractEndpoint> { - private final HealthIndicator indicator; + @Autowired(required = false) + private Map> healthIndicators; /** * Create a new {@link HealthIndicator} instance. - * - * @param indicator the health indicator */ - public HealthEndpoint(HealthIndicator indicator) { + public HealthEndpoint() { super("health", false, true); - Assert.notNull(indicator, "Indicator must not be null"); - this.indicator = indicator; } + /** + * Invoke all {@link HealthIndicator} delegates and collect their health information. + */ @Override - public T invoke() { - return this.indicator.health(); + public Map invoke() { + Map health = new LinkedHashMap(); + for (Entry> entry : this.healthIndicators.entrySet()) { + health.put(getKey(entry.getKey()), entry.getValue().health()); + } + return health; } + /** + * Turns the bean name into a key that can be used in the map of health information. + */ + private String getKey(String name) { + int x = name.toLowerCase().indexOf("healthindicator"); + if (x > 0) { + return name.substring(0, x); + } + return name; + } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/MongoHealthIndicator.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/MongoHealthIndicator.java new file mode 100644 index 00000000000..080602e6c3f --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/MongoHealthIndicator.java @@ -0,0 +1,57 @@ +/* + * Copyright 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.springframework.data.mongodb.core.MongoTemplate; + +import com.mongodb.CommandResult; + +/** + * Simple implementation of a {@link HealthIndicator} returning status information for + * Mongo data stores. + * + * @author Christian Dupuis + * @since 1.1.0 + */ +public class MongoHealthIndicator implements HealthIndicator> { + + private final MongoTemplate mongoTemplate; + + public MongoHealthIndicator(MongoTemplate mongoTemplate) { + this.mongoTemplate = mongoTemplate; + } + + @Override + public Map health() { + Map health = new HashMap(); + try { + CommandResult result = this.mongoTemplate + .executeCommand("{ serverStatus: 1 }"); + health.put("status", "ok"); + health.put("version", result.getString("version")); + } + catch (Exception ex) { + health.put("status", "error"); + health.put("error", ex.getClass().getName() + ": " + ex.getMessage()); + } + return health; + } + +} diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/RedisHealthIndicator.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/RedisHealthIndicator.java new file mode 100644 index 00000000000..fe5e3425240 --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/RedisHealthIndicator.java @@ -0,0 +1,63 @@ +/* + * Copyright 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 java.util.Properties; + +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisConnectionUtils; + +/** + * Simple implementation of a {@link HealthIndicator} returning status information for + * Redis data stores. + * + * @author Christian Dupuis + * @since 1.1.0 + */ +public class RedisHealthIndicator implements HealthIndicator> { + + private final RedisConnectionFactory redisConnectionFactory; + + public RedisHealthIndicator(RedisConnectionFactory connectionFactory) { + this.redisConnectionFactory = connectionFactory; + } + + @Override + public Map health() { + Map health = new HashMap(); + + RedisConnection connection = null; + try { + connection = RedisConnectionUtils.getConnection(this.redisConnectionFactory); + Properties info = connection.info(); + health.put("status", "ok"); + health.put("version", info.getProperty("redis_version")); + } + catch (Exception ex) { + health.put("status", "error"); + health.put("error", ex.getClass().getName() + ": " + ex.getMessage()); + } + finally { + RedisConnectionUtils.releaseConnection(connection, + this.redisConnectionFactory); + } + return health; + } +} diff --git a/spring-boot-actuator/src/main/resources/META-INF/spring.factories b/spring-boot-actuator/src/main/resources/META-INF/spring.factories index d8adc535491..83904646373 100644 --- a/spring-boot-actuator/src/main/resources/META-INF/spring.factories +++ b/spring-boot-actuator/src/main/resources/META-INF/spring.factories @@ -4,6 +4,7 @@ org.springframework.boot.actuate.autoconfigure.CrshAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.EndpointMBeanExportAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration,\ +org.springframework.boot.actuate.autoconfigure.HealthIndicatorAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration,\ diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfigurationTests.java index c8dd1ee5e6b..bd279879e2f 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfigurationTests.java @@ -43,7 +43,7 @@ import static org.junit.Assert.assertTrue; /** * Tests for {@link EndpointAutoConfiguration}. - * + * * @author Dave Syer * @author Phillip Webb * @author Greg Turnquist @@ -80,18 +80,33 @@ public class EndpointAutoConfigurationTests { } @Test + @SuppressWarnings("unchecked") public void healthEndpoint() { this.context = new AnnotationConfigApplicationContext(); - this.context.register(EndpointAutoConfiguration.class, - EmbeddedDataSourceConfiguration.class); + this.context.register(EmbeddedDataSourceConfiguration.class, + EndpointAutoConfiguration.class, HealthIndicatorAutoConfiguration.class); this.context.refresh(); - HealthEndpoint bean = this.context.getBean(HealthEndpoint.class); + HealthEndpoint bean = this.context.getBean(HealthEndpoint.class); assertNotNull(bean); - @SuppressWarnings("unchecked") - Map result = (Map) bean.invoke(); + Map result = bean.invoke(); + assertNotNull(result); + assertTrue("Wrong result: " + result, + ((Map) result.get("db")).containsKey("status")); + assertTrue("Wrong result: " + result, + ((Map) result.get("db")).containsKey("database")); + } + + @Test + public void healthEndpointWithDefaultHealthIndicator() { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(EndpointAutoConfiguration.class, + HealthIndicatorAutoConfiguration.class); + this.context.refresh(); + HealthEndpoint bean = this.context.getBean(HealthEndpoint.class); + assertNotNull(bean); + Map result = bean.invoke(); assertNotNull(result); assertTrue("Wrong result: " + result, result.containsKey("status")); - assertTrue("Wrong result: " + result, result.containsKey("database")); } @Test diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfigurationTests.java new file mode 100644 index 00000000000..96c1aec4047 --- /dev/null +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/HealthIndicatorAutoConfigurationTests.java @@ -0,0 +1,127 @@ +/* + * Copyright 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.autoconfigure; + +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.actuate.health.MongoHealthIndicator; +import org.springframework.boot.actuate.health.RedisHealthIndicator; +import org.springframework.boot.actuate.health.SimpleHealthIndicator; +import org.springframework.boot.actuate.health.VanillaHealthIndicator; +import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration; +import org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import static org.junit.Assert.assertEquals; + +/** + * Tests for {@link HealthIndicatorAutoConfiguration}. + * + * @author Christian Dupuis + * @since 1.1.0 + */ +public class HealthIndicatorAutoConfigurationTests { + + private AnnotationConfigApplicationContext context; + + @Before + public void setup() { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(EndpointAutoConfiguration.class); + this.context.refresh(); + } + + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + + @SuppressWarnings("rawtypes") + @Test + public void defaultHealthIndicator() { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(HealthIndicatorAutoConfiguration.class); + this.context.refresh(); + Map beans = this.context + .getBeansOfType(HealthIndicator.class); + assertEquals(1, beans.size()); + assertEquals(VanillaHealthIndicator.class, beans.values().iterator().next() + .getClass()); + } + + @SuppressWarnings("rawtypes") + @Test + public void redisHealthIndicator() { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(RedisAutoConfiguration.class, + HealthIndicatorAutoConfiguration.class); + this.context.refresh(); + Map beans = this.context + .getBeansOfType(HealthIndicator.class); + assertEquals(1, beans.size()); + assertEquals(RedisHealthIndicator.class, beans.values().iterator().next() + .getClass()); + } + + @SuppressWarnings("rawtypes") + @Test + public void mongoHealthIndicator() { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(MongoAutoConfiguration.class, + MongoDataAutoConfiguration.class, HealthIndicatorAutoConfiguration.class); + this.context.refresh(); + Map beans = this.context + .getBeansOfType(HealthIndicator.class); + assertEquals(1, beans.size()); + assertEquals(MongoHealthIndicator.class, beans.values().iterator().next() + .getClass()); + } + + @SuppressWarnings("rawtypes") + @Test + public void combinedHealthIndicator() { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(MongoAutoConfiguration.class, RedisAutoConfiguration.class, + MongoDataAutoConfiguration.class, HealthIndicatorAutoConfiguration.class); + this.context.refresh(); + Map beans = this.context + .getBeansOfType(HealthIndicator.class); + assertEquals(2, beans.size()); + } + + @SuppressWarnings("rawtypes") + @Test + public void dataSourceHealthIndicator() { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(EmbeddedDataSourceConfiguration.class, + HealthIndicatorAutoConfiguration.class); + this.context.refresh(); + Map beans = this.context + .getBeansOfType(HealthIndicator.class); + assertEquals(1, beans.size()); + assertEquals(SimpleHealthIndicator.class, beans.values().iterator().next() + .getClass()); + } +} \ No newline at end of file diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/HealthEndpointTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/HealthEndpointTests.java index e56f77380c6..7be942a0fdc 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/HealthEndpointTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/HealthEndpointTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 the original author or authors. + * 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. @@ -16,6 +16,9 @@ package org.springframework.boot.actuate.endpoint; +import java.util.HashMap; +import java.util.Map; + import org.junit.Test; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -27,10 +30,10 @@ import static org.junit.Assert.assertThat; /** * Tests for {@link HealthEndpoint}. - * + * * @author Phillip Webb */ -public class HealthEndpointTests extends AbstractEndpointTests> { +public class HealthEndpointTests extends AbstractEndpointTests { public HealthEndpointTests() { super(Config.class, HealthEndpoint.class, "health", false, "endpoints.health"); @@ -38,7 +41,9 @@ public class HealthEndpointTests extends AbstractEndpointTests result = new HashMap(); + result.put("status", "fine"); + assertThat(getEndpointBean().invoke(), equalTo(result)); } @Configuration @@ -46,14 +51,18 @@ public class HealthEndpointTests extends AbstractEndpointTests endpoint() { - return new HealthEndpoint(new HealthIndicator() { + public HealthEndpoint endpoint() { + return new HealthEndpoint(); + } + + @Bean + public HealthIndicator statusHealthIndicator() { + return new HealthIndicator() { @Override public String health() { return "fine"; } - }); + }; } - } } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/MongoHealthIndicatorTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/MongoHealthIndicatorTests.java new file mode 100644 index 00000000000..8d2b89f0d2d --- /dev/null +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/MongoHealthIndicatorTests.java @@ -0,0 +1,63 @@ +/* + * Copyright 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 org.junit.After; +import org.junit.Test; +import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.HealthIndicatorAutoConfiguration; +import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.data.mongodb.core.MongoTemplate; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Tests for {@link MongoHealthIndicator}. + * + * @author Christian Dupuis + * @since 1.1.0 + */ +public class MongoHealthIndicatorTests { + + private AnnotationConfigApplicationContext context; + + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void healthIndicatorExists() { + this.context = new AnnotationConfigApplicationContext( + PropertyPlaceholderAutoConfiguration.class, MongoAutoConfiguration.class, + MongoDataAutoConfiguration.class, EndpointAutoConfiguration.class, + HealthIndicatorAutoConfiguration.class); + assertEquals(1, this.context.getBeanNamesForType(MongoTemplate.class).length); + MongoHealthIndicator healthIndicator = this.context + .getBean(MongoHealthIndicator.class); + assertNotNull(healthIndicator); + } + + // TODO add tests for actual health check + +} diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/RedisHealthIndicatorTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/RedisHealthIndicatorTests.java new file mode 100644 index 00000000000..576bd108088 --- /dev/null +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/RedisHealthIndicatorTests.java @@ -0,0 +1,62 @@ +/* + * Copyright 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 org.junit.After; +import org.junit.Test; +import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.HealthIndicatorAutoConfiguration; +import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.data.redis.connection.RedisConnectionFactory; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Tests for {@link RedisHealthIndicator}. + * + * @author Christian Dupuis + * @since 1.1.0 + */ +public class RedisHealthIndicatorTests { + + private AnnotationConfigApplicationContext context; + + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void healthIndicatorExists() { + this.context = new AnnotationConfigApplicationContext( + PropertyPlaceholderAutoConfiguration.class, RedisAutoConfiguration.class, + EndpointAutoConfiguration.class, HealthIndicatorAutoConfiguration.class); + assertEquals(1, + this.context.getBeanNamesForType(RedisConnectionFactory.class).length); + RedisHealthIndicator healthIndicator = this.context + .getBean(RedisHealthIndicator.class); + assertNotNull(healthIndicator); + } + + // TODO add tests for actual health check + +}