From b026b13c664d72566ddd5e08a647d2df2ed230f8 Mon Sep 17 00:00:00 2001 From: Christian Dupuis Date: Sat, 10 May 2014 11:10:29 +0200 Subject: [PATCH] Add HealthIndicator for Rabbit --- spring-boot-actuator/pom.xml | 5 ++ .../HealthIndicatorAutoConfiguration.java | 32 ++++++++- .../actuate/health/RabbitHealthIndicator.java | 67 +++++++++++++++++++ .../health/RabbitHealthIndicatorTests.java | 59 ++++++++++++++++ 4 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/RabbitHealthIndicator.java create mode 100644 spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/RabbitHealthIndicatorTests.java diff --git a/spring-boot-actuator/pom.xml b/spring-boot-actuator/pom.xml index 1ecb5e8bc6..8b9c5e9310 100644 --- a/spring-boot-actuator/pom.xml +++ b/spring-boot-actuator/pom.xml @@ -111,6 +111,11 @@ jedis true + + org.springframework.amqp + spring-rabbit + true + ch.qos.logback 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 index f22d11c8c2..bf648ac201 100644 --- 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 @@ -20,15 +20,18 @@ import java.util.Map; import javax.sql.DataSource; +import org.springframework.amqp.rabbit.core.RabbitTemplate; 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.RabbitHealthIndicator; import org.springframework.boot.actuate.health.RedisHealthIndicator; import org.springframework.boot.actuate.health.SimpleDataSourceHealthIndicator; import org.springframework.boot.actuate.health.VanillaHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.jdbc.CommonsDataSourceConfiguration; @@ -46,7 +49,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; /** * {@link EnableAutoConfiguration Auto-configuration} for {@link HealthIndicator}s. - * + * * @author Christian Dupuis * @since 1.1.0 */ @@ -55,7 +58,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; EmbeddedDataSourceConfiguration.class, CommonsDataSourceConfiguration.class, HikariDataSourceConfiguration.class, TomcatDataSourceConfiguration.class, MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, - RedisAutoConfiguration.class }) + RedisAutoConfiguration.class, RabbitAutoConfiguration.class }) public class HealthIndicatorAutoConfiguration { @Bean @@ -137,4 +140,29 @@ public class HealthIndicatorAutoConfiguration { } } + @Configuration + @ConditionalOnBean(RabbitTemplate.class) + public static class RabbitHealthIndicatorConfiguration { + + @Autowired + private Map rabbitTemplates; + + @Bean + @ConditionalOnMissingBean(name = "rabbitHealthIndicator") + public HealthIndicator redisHealthIndicator() { + if (this.rabbitTemplates.size() == 1) { + return new RabbitHealthIndicator(this.rabbitTemplates.values().iterator() + .next()); + } + + CompositeHealthIndicator composite = new CompositeHealthIndicator(); + for (Map.Entry entry : this.rabbitTemplates + .entrySet()) { + composite.addHealthIndicator(entry.getKey(), new RabbitHealthIndicator( + entry.getValue())); + } + return composite; + } + } + } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/RabbitHealthIndicator.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/RabbitHealthIndicator.java new file mode 100644 index 0000000000..70a00ff6ec --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/RabbitHealthIndicator.java @@ -0,0 +1,67 @@ +/* + * 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.springframework.amqp.rabbit.core.ChannelCallback; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.util.Assert; + +import com.rabbitmq.client.Channel; + +/** + * Simple implementation of a {@link HealthIndicator} returning status information for the + * RabbitMQ messaging system. + * + * @author Christian Dupuis + * @since 1.1.0 + */ +public class RabbitHealthIndicator implements HealthIndicator> { + + private final RabbitTemplate rabbitTemplate; + + public RabbitHealthIndicator(RabbitTemplate rabbitTemplate) { + Assert.notNull(rabbitTemplate, "RabbitTemplate must not be null."); + this.rabbitTemplate = rabbitTemplate; + } + + @Override + public Map health() { + Map health = new HashMap(); + try { + health.put("version", + this.rabbitTemplate.execute(new ChannelCallback() { + + @Override + public String doInRabbit(Channel channel) throws Exception { + Map serverProperties = channel + .getConnection().getServerProperties(); + return serverProperties.get("version").toString(); + } + })); + + health.put("status", "ok"); + } + catch (Exception ex) { + health.put("status", "error"); + health.put("error", ex.getClass().getName() + ": " + ex.getMessage()); + } + return health; + } +} diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/RabbitHealthIndicatorTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/RabbitHealthIndicatorTests.java new file mode 100644 index 0000000000..0c372ed315 --- /dev/null +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/RabbitHealthIndicatorTests.java @@ -0,0 +1,59 @@ +/* + * 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.amqp.rabbit.core.RabbitAdmin; +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.amqp.RabbitAutoConfiguration; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Tests for {@link RabbitHealthIndicator}. + * + * @author Christian Dupuis + */ +public class RabbitHealthIndicatorTests { + + private AnnotationConfigApplicationContext context; + + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void indicatorExists() { + this.context = new AnnotationConfigApplicationContext( + PropertyPlaceholderAutoConfiguration.class, + RabbitAutoConfiguration.class, EndpointAutoConfiguration.class, + HealthIndicatorAutoConfiguration.class); + assertEquals(1, this.context.getBeanNamesForType(RabbitAdmin.class).length); + RabbitHealthIndicator healthIndicator = this.context + .getBean(RabbitHealthIndicator.class); + assertNotNull(healthIndicator); + } + +}