From a8318d759ceb1e19585abfb36c283a5566d75d21 Mon Sep 17 00:00:00 2001 From: John Blum Date: Tue, 18 Sep 2018 22:50:47 -0700 Subject: [PATCH] Add Spring Boot, Apache Geode HealthIndicator auto-configuration module. --- ...spring-geode-actuator-autoconfigure.gradle | 22 ++++ ...GeodeHealthIndicatorAutoConfiguration.java | 54 +++++++++ ...BaseGeodeHealthIndicatorConfiguration.java | 65 ++++++++++ ...ientCacheHealthIndicatorConfiguration.java | 71 +++++++++++ ...PeerCacheHealthIndicatorConfiguration.java | 112 ++++++++++++++++++ .../main/resources/META-INF/spring.factories | 2 + 6 files changed, 326 insertions(+) create mode 100644 spring-geode-actuator-autoconfigure/spring-geode-actuator-autoconfigure.gradle create mode 100644 spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/GeodeHealthIndicatorAutoConfiguration.java create mode 100644 spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/config/BaseGeodeHealthIndicatorConfiguration.java create mode 100644 spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/config/ClientCacheHealthIndicatorConfiguration.java create mode 100644 spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/config/PeerCacheHealthIndicatorConfiguration.java create mode 100644 spring-geode-actuator-autoconfigure/src/main/resources/META-INF/spring.factories diff --git a/spring-geode-actuator-autoconfigure/spring-geode-actuator-autoconfigure.gradle b/spring-geode-actuator-autoconfigure/spring-geode-actuator-autoconfigure.gradle new file mode 100644 index 00000000..65031e0a --- /dev/null +++ b/spring-geode-actuator-autoconfigure/spring-geode-actuator-autoconfigure.gradle @@ -0,0 +1,22 @@ +apply plugin: 'io.spring.convention.spring-module' + +description = "Spring Boot for Apache Geode Actuator Auto-Configuration" + +dependencies { + + compile project(":spring-geode-autoconfigure") + compile project(":spring-geode-actuator") + + testCompile "org.assertj:assertj-core" + testCompile "junit:junit" + testCompile "org.mockito:mockito-core" + testCompile "org.projectlombok:lombok" + testCompile "edu.umd.cs.mtc:multithreadedtc" + + testCompile("org.springframework.boot:spring-boot-starter-test") { + exclude group: "org.springframework.boot", module: "spring-boot-starter-logging" + } + + testCompile "org.springframework.data:spring-data-geode-test" + testCompile slf4jDependencies +} diff --git a/spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/GeodeHealthIndicatorAutoConfiguration.java b/spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/GeodeHealthIndicatorAutoConfiguration.java new file mode 100644 index 00000000..209b4d38 --- /dev/null +++ b/spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/GeodeHealthIndicatorAutoConfiguration.java @@ -0,0 +1,54 @@ +/* + * Copyright 2018 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.geode.boot.actuate.autoconfigure; + +import org.apache.geode.cache.GemFireCache; +import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.gemfire.CacheFactoryBean; +import org.springframework.geode.boot.actuate.autoconfigure.config.BaseGeodeHealthIndicatorConfiguration; +import org.springframework.geode.boot.actuate.autoconfigure.config.ClientCacheHealthIndicatorConfiguration; +import org.springframework.geode.boot.actuate.autoconfigure.config.PeerCacheHealthIndicatorConfiguration; +import org.springframework.geode.boot.autoconfigure.ClientCacheAutoConfiguration; + +/** + * The GeodeHealthIndicatorAutoConfiguration class... + * + * @author John Blum + * @since 1.0.0 + */ +@Configuration +@AutoConfigureAfter(ClientCacheAutoConfiguration.class) +@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class) +@ConditionalOnBean(GemFireCache.class) +@ConditionalOnClass({ GemFireCache.class, CacheFactoryBean.class }) +@ConditionalOnEnabledHealthIndicator("geode") +@Import({ + BaseGeodeHealthIndicatorConfiguration.class, + ClientCacheHealthIndicatorConfiguration.class, + PeerCacheHealthIndicatorConfiguration.class, +}) +@SuppressWarnings("unused") +public class GeodeHealthIndicatorAutoConfiguration { + +} diff --git a/spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/config/BaseGeodeHealthIndicatorConfiguration.java b/spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/config/BaseGeodeHealthIndicatorConfiguration.java new file mode 100644 index 00000000..7ce0c513 --- /dev/null +++ b/spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/config/BaseGeodeHealthIndicatorConfiguration.java @@ -0,0 +1,65 @@ +/* + * Copyright 2018 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.geode.boot.actuate.autoconfigure.config; + +import org.apache.geode.cache.GemFireCache; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.geode.boot.actuate.GeodeCacheHealthIndicator; +import org.springframework.geode.boot.actuate.GeodeDiskStoresHealthIndicator; +import org.springframework.geode.boot.actuate.GeodeIndexesHealthIndicator; +import org.springframework.geode.boot.actuate.GeodeRegionsHealthIndicator; + +/** + * The BaseGeodeHealthIndicatorConfiguration class... + * + * @author John Blum + * @see org.apache.geode.cache.GemFireCache + * @see org.springframework.context.ApplicationContext + * @see org.springframework.context.annotation.Bean + * @see org.springframework.context.annotation.Configuration + * @see org.springframework.geode.boot.actuate.GeodeCacheHealthIndicator + * @see org.springframework.geode.boot.actuate.GeodeDiskStoresHealthIndicator + * @see org.springframework.geode.boot.actuate.GeodeIndexesHealthIndicator + * @see org.springframework.geode.boot.actuate.GeodeRegionsHealthIndicator + * @since 1.0.0 + */ +@Configuration +@SuppressWarnings("unused") +public class BaseGeodeHealthIndicatorConfiguration { + + @Bean("GeodeCacheHealthIndicator") + GeodeCacheHealthIndicator cacheHealthIndicator(GemFireCache gemfireCache) { + return new GeodeCacheHealthIndicator(gemfireCache); + } + + @Bean("GeodeDiskStoresHealthIndicator") + GeodeDiskStoresHealthIndicator diskStoresHealthIndicator(ApplicationContext applicationContext) { + return new GeodeDiskStoresHealthIndicator(applicationContext); + } + + @Bean("GeodeIndexesHealthIndicator") + GeodeIndexesHealthIndicator indexesHealthIndicator(ApplicationContext applicationContext) { + return new GeodeIndexesHealthIndicator(applicationContext); + } + + @Bean("GeodeRegionsHealthIndicator") + GeodeRegionsHealthIndicator regionsHealthIndicator(GemFireCache gemfireCache) { + return new GeodeRegionsHealthIndicator(gemfireCache); + } +} diff --git a/spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/config/ClientCacheHealthIndicatorConfiguration.java b/spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/config/ClientCacheHealthIndicatorConfiguration.java new file mode 100644 index 00000000..44aa9110 --- /dev/null +++ b/spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/config/ClientCacheHealthIndicatorConfiguration.java @@ -0,0 +1,71 @@ +/* + * Copyright 2018 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.geode.boot.actuate.autoconfigure.config; + +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.GemFireCache; +import org.apache.geode.cache.client.ClientCache; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.type.AnnotatedTypeMetadata; +import org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer; +import org.springframework.data.gemfire.util.CacheUtils; +import org.springframework.geode.boot.actuate.GeodeContinuousQueriesHealthIndicator; +import org.springframework.geode.boot.actuate.GeodePoolsHealthIndicator; + +/** + * The ClientCacheHealthIndicatorConfiguration class... + * + * @author John Blum + * @see org.springframework.geode.boot.actuate.GeodeContinuousQueriesHealthIndicator + * @see org.springframework.geode.boot.actuate.GeodePoolsHealthIndicator + * @since 1.0.0 + */ +@Configuration +@Conditional(ClientCacheHealthIndicatorConfiguration.ClientCacheCondition.class) +@SuppressWarnings("unused") +public class ClientCacheHealthIndicatorConfiguration { + + @Bean("GeodeContinuousQueryHealthIndicator") + GeodeContinuousQueriesHealthIndicator continuousQueriesHealthIndicator( + @Autowired(required = false) ContinuousQueryListenerContainer continuousQueryListenerContainer) { + + return new GeodeContinuousQueriesHealthIndicator(continuousQueryListenerContainer); + } + + @Bean("GeodePoolsHealthIndicator") + GeodePoolsHealthIndicator poolsHealthIndicator(GemFireCache gemfireCache) { + return new GeodePoolsHealthIndicator(gemfireCache); + } + + public static final class ClientCacheCondition implements Condition { + + @Override @SuppressWarnings("all") + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + + Cache peerCache = CacheUtils.getCache(); + + ClientCache clientCache = CacheUtils.getClientCache(); + + return clientCache != null || peerCache == null; + } + } +} diff --git a/spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/config/PeerCacheHealthIndicatorConfiguration.java b/spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/config/PeerCacheHealthIndicatorConfiguration.java new file mode 100644 index 00000000..c745a304 --- /dev/null +++ b/spring-geode-actuator-autoconfigure/src/main/java/org/springframework/geode/boot/actuate/autoconfigure/config/PeerCacheHealthIndicatorConfiguration.java @@ -0,0 +1,112 @@ +/* + * Copyright 2018 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.geode.boot.actuate.autoconfigure.config; + +import java.util.Optional; + +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.GemFireCache; +import org.apache.geode.cache.client.ClientCache; +import org.apache.geode.cache.server.CacheServer; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.type.AnnotatedTypeMetadata; +import org.springframework.data.gemfire.util.CacheUtils; +import org.springframework.geode.boot.actuate.GeodeAsyncEventQueuesHealthIndicator; +import org.springframework.geode.boot.actuate.GeodeCacheServersHealthIndicator; +import org.springframework.geode.boot.actuate.GeodeGatewayReceiversHealthIndicator; +import org.springframework.geode.boot.actuate.GeodeGatewaySendersHealthIndicator; +import org.springframework.geode.boot.actuate.health.support.ActuatorServerLoadProbeWrapper; +import org.springframework.lang.Nullable; + +/** + * The PeerCacheHealthIndicatorConfiguration class... + * + * @author John Blum + * @see org.springframework.geode.boot.actuate.GeodeAsyncEventQueuesHealthIndicator + * @see org.springframework.geode.boot.actuate.GeodeCacheServersHealthIndicator + * @see org.springframework.geode.boot.actuate.GeodeGatewayReceiversHealthIndicator + * @see org.springframework.geode.boot.actuate.GeodeGatewaySendersHealthIndicator + * @since 1.0.0 + */ +@Configuration +@Conditional(PeerCacheHealthIndicatorConfiguration.PeerCacheCondition.class) +@SuppressWarnings("unused") +public class PeerCacheHealthIndicatorConfiguration { + + @Bean("GeodeAsyncEventQueuesHealthIndicator") + GeodeAsyncEventQueuesHealthIndicator asyncEventQueuesHealthIndicator(GemFireCache gemfireCache) { + return new GeodeAsyncEventQueuesHealthIndicator(gemfireCache); + } + + @Bean("GeodeCacheServersHealthIndicator") + GeodeCacheServersHealthIndicator cacheServersHealthIndicator(GemFireCache gemfireCache) { + return new GeodeCacheServersHealthIndicator(gemfireCache); + } + + @Bean("GeodeGatewayReceiversHealthIndicator") + GeodeGatewayReceiversHealthIndicator gatewayReceiversHealthIndicator(GemFireCache gemfireCache) { + return new GeodeGatewayReceiversHealthIndicator(gemfireCache); + } + + @Bean("GeodeGatewaySendersHealthIndicator") + GeodeGatewaySendersHealthIndicator gatewaySendersHealthIndicator(GemFireCache gemfireCache) { + return new GeodeGatewaySendersHealthIndicator(gemfireCache); + } + + @Bean + BeanPostProcessor cacheServerLoadProbeWrappingBeanPostProcessor() { + + return new BeanPostProcessor() { + + @Nullable @Override @SuppressWarnings("all") + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + + if (bean instanceof CacheServer) { + + CacheServer cacheServer = (CacheServer) bean; + + Optional.ofNullable(cacheServer.getLoadProbe()) + .filter(it -> !cacheServer.isRunning()) + .filter(it -> cacheServer.getLoadPollInterval() > 0) + .ifPresent(serverLoadProbe -> + cacheServer.setLoadProbe(new ActuatorServerLoadProbeWrapper(serverLoadProbe))); + } + + return bean; + } + }; + } + + public static final class PeerCacheCondition implements Condition { + + @Override @SuppressWarnings("all") + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + + Cache peerCache = CacheUtils.getCache(); + + ClientCache clientCache = CacheUtils.getClientCache(); + + return peerCache != null || clientCache == null; + } + } +} diff --git a/spring-geode-actuator-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-geode-actuator-autoconfigure/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..377938b0 --- /dev/null +++ b/spring-geode-actuator-autoconfigure/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.geode.boot.actuate.autoconfigure.GeodeHealthIndicatorAutoConfiguration