From fca5a2b8246c42d3e634826ccd231bf5a15c22ed Mon Sep 17 00:00:00 2001 From: Dmytro Nosan Date: Fri, 12 Jul 2019 16:30:28 +0300 Subject: [PATCH 1/2] Add HealthIndicator for Hazelcast See gh-17499 --- .../pom.xml | 5 ++ ...lcastHealthIndicatorAutoConfiguration.java | 60 +++++++++++++++ .../autoconfigure/hazelcast/package-info.java | 20 +++++ ...atorAutoConfigurationIntegrationTests.java | 76 +++++++++++++++++++ ...HealthIndicatorAutoConfigurationTests.java | 55 ++++++++++++++ .../hazelcast/HazelcastHealthIndicator.java | 63 +++++++++++++++ .../boot/actuate/hazelcast/package-info.java | 20 +++++ .../HazelcastHealthIndicatorTests.java | 66 ++++++++++++++++ 8 files changed, 365 insertions(+) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/package-info.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationIntegrationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicator.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/package-info.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicatorTests.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml index 9783a666d28..394fa29dac8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml @@ -64,6 +64,11 @@ hazelcast-spring true + + com.hazelcast + hazelcast-client + test + com.sun.mail jakarta.mail diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfiguration.java new file mode 100644 index 00000000000..097b7f3bdfa --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfiguration.java @@ -0,0 +1,60 @@ +/* + * 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.autoconfigure.hazelcast; + +import java.util.Map; + +import com.hazelcast.core.HazelcastInstance; + +import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthIndicatorConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration; +import org.springframework.boot.actuate.hazelcast.HazelcastHealthIndicator; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for + * {@link HazelcastHealthIndicator}. + * + * @author Dmytro Nosan + * @since 2.2.0 + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(HazelcastInstance.class) +@ConditionalOnBean(HazelcastInstance.class) +@ConditionalOnEnabledHealthIndicator("hazelcast") +@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class) +@AutoConfigureAfter(HazelcastAutoConfiguration.class) +public class HazelcastHealthIndicatorAutoConfiguration + extends CompositeHealthIndicatorConfiguration { + + @Bean + @ConditionalOnMissingBean(name = "hazelcastHealthIndicator") + public HealthIndicator hazelcastHealthIndicator(Map hazelcastInstances) { + return createHealthIndicator(hazelcastInstances); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/package-info.java new file mode 100644 index 00000000000..58d63614e04 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Auto-configuration for Hazelcast's actuator. + */ +package org.springframework.boot.actuate.autoconfigure.hazelcast; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationIntegrationTests.java new file mode 100644 index 00000000000..8056ceef9b5 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationIntegrationTests.java @@ -0,0 +1,76 @@ +/* + * 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.autoconfigure.hazelcast; + +import com.hazelcast.client.config.ClientConfig; +import com.hazelcast.config.Config; +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration; +import org.springframework.boot.actuate.hazelcast.HazelcastHealthIndicator; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.Status; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link HazelcastHealthIndicatorAutoConfiguration}. + * + * @author Dmytro Nosan + */ +class HazelcastHealthIndicatorAutoConfigurationIntegrationTests { + + private final HazelcastInstance hazelcastServer = Hazelcast.newHazelcastInstance(new Config()); + + private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withBean(ClientConfig.class) + .withConfiguration(AutoConfigurations.of(HazelcastHealthIndicatorAutoConfiguration.class, + HazelcastAutoConfiguration.class, HealthIndicatorAutoConfiguration.class)); + + @AfterEach + void shutdown() { + this.hazelcastServer.shutdown(); + } + + @Test + void hazelcastUp() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(HazelcastInstance.class).hasSingleBean(HazelcastHealthIndicator.class); + HazelcastInstance hazelcast = context.getBean(HazelcastInstance.class); + Health health = context.getBean(HazelcastHealthIndicator.class).health(); + assertThat(health.getStatus()).isEqualTo(Status.UP); + assertThat(health.getDetails()).containsOnlyKeys("name", "uuid").containsEntry("name", hazelcast.getName()) + .containsEntry("uuid", hazelcast.getLocalEndpoint().getUuid()); + }); + } + + @Test + void hazelcastDown() { + this.contextRunner.run((context) -> { + shutdown(); + assertThat(context).hasSingleBean(HazelcastHealthIndicator.class); + Health health = context.getBean(HazelcastHealthIndicator.class).health(); + assertThat(health.getStatus()).isEqualTo(Status.DOWN); + }); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationTests.java new file mode 100644 index 00000000000..a980c6db548 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationTests.java @@ -0,0 +1,55 @@ +/* + * 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.autoconfigure.hazelcast; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration; +import org.springframework.boot.actuate.hazelcast.HazelcastHealthIndicator; +import org.springframework.boot.actuate.health.ApplicationHealthIndicator; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link HazelcastHealthIndicatorAutoConfiguration}. + * + * @author Dmytro Nosan + */ +class HazelcastHealthIndicatorAutoConfigurationTests { + + private ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(HazelcastAutoConfiguration.class, + HazelcastHealthIndicatorAutoConfiguration.class, HealthIndicatorAutoConfiguration.class)); + + @Test + void runShouldCreateIndicator() { + this.contextRunner.run((context) -> assertThat(context).hasSingleBean(HazelcastHealthIndicator.class) + .doesNotHaveBean(ApplicationHealthIndicator.class)); + } + + @Test + void runWhenDisabledShouldNotCreateIndicator() { + this.contextRunner.withPropertyValues("management.health.hazelcast.enabled:false") + .run((context) -> assertThat(context).doesNotHaveBean(HazelcastHealthIndicator.class) + .doesNotHaveBean(HazelcastHealthIndicator.class) + .hasSingleBean(ApplicationHealthIndicator.class)); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicator.java new file mode 100644 index 00000000000..42d531b5d92 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicator.java @@ -0,0 +1,63 @@ +/* + * 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.hazelcast; + +import java.util.LinkedHashMap; +import java.util.Map; + +import com.hazelcast.core.Endpoint; +import com.hazelcast.core.HazelcastInstance; +import com.hazelcast.transaction.TransactionalTask; + +import org.springframework.boot.actuate.health.AbstractHealthIndicator; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.util.Assert; + +/** + * {@link HealthIndicator} for a Hazelcast. + * + * @author Dmytro Nosan + * @since 2.2.0 + */ +public class HazelcastHealthIndicator extends AbstractHealthIndicator { + + private static final TransactionalTask TASK = (context) -> null; + + private final HazelcastInstance hazelcast; + + public HazelcastHealthIndicator(HazelcastInstance hazelcast) { + super("Hazelcast health check failed"); + Assert.notNull(hazelcast, "HazelcastInstance must not be null"); + this.hazelcast = hazelcast; + } + + @Override + protected void doHealthCheck(Health.Builder builder) { + this.hazelcast.executeTransaction(TASK); + builder.up().withDetails(getDetails()); + } + + private Map getDetails() { + Map details = new LinkedHashMap<>(); + Endpoint endpoint = this.hazelcast.getLocalEndpoint(); + details.put("name", this.hazelcast.getName()); + details.put("uuid", endpoint.getUuid()); + return details; + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/package-info.java new file mode 100644 index 00000000000..44e785578dc --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Actuator support for Hazelcast. + */ +package org.springframework.boot.actuate.hazelcast; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicatorTests.java new file mode 100644 index 00000000000..a8dd1d2841a --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicatorTests.java @@ -0,0 +1,66 @@ +/* + * 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.hazelcast; + +import com.hazelcast.core.Endpoint; +import com.hazelcast.core.HazelcastException; +import com.hazelcast.core.HazelcastInstance; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.Status; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link HazelcastHealthIndicator}. + * + * @author Dmytro Nosan + */ +class HazelcastHealthIndicatorTests { + + private final HazelcastInstance hazelcast = mock(HazelcastInstance.class); + + private final HazelcastHealthIndicator healthIndicator = new HazelcastHealthIndicator(this.hazelcast); + + @Test + void hazelcastUp() { + Endpoint endpoint = mock(Endpoint.class); + when(this.hazelcast.getName()).thenReturn("hz0-instance"); + when(this.hazelcast.getLocalEndpoint()).thenReturn(endpoint); + when(endpoint.getUuid()).thenReturn("7581bb2f-879f-413f-b574-0071d7519eb0"); + + Health health = this.healthIndicator.health(); + + assertThat(health.getStatus()).isEqualTo(Status.UP); + assertThat(health.getDetails()).containsOnlyKeys("name", "uuid").containsEntry("name", "hz0-instance") + .containsEntry("uuid", "7581bb2f-879f-413f-b574-0071d7519eb0"); + } + + @Test + void hazelcastDown() { + when(this.hazelcast.executeTransaction(any())).thenThrow(new HazelcastException()); + + Health health = this.healthIndicator.health(); + + assertThat(health.getStatus()).isEqualTo(Status.DOWN); + } + +} From be988d7072bf4b5aea2e4c9f10cb1e7fc4e99c12 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 18 Jul 2019 14:58:39 +0200 Subject: [PATCH 2/2] Polish "Add HealthIndicator for Hazelcast" See gh-17499 --- .../pom.xml | 5 ---- .../autoconfigure/hazelcast/package-info.java | 2 +- ...atorAutoConfigurationIntegrationTests.java | 15 ++--------- ...HealthIndicatorAutoConfigurationTests.java | 1 - .../hazelcast/HazelcastHealthIndicator.java | 25 ++++++------------- .../HazelcastHealthIndicatorTests.java | 16 ++++++------ .../asciidoc/production-ready-features.adoc | 3 +++ 7 files changed, 21 insertions(+), 46 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml index 394fa29dac8..9783a666d28 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml @@ -64,11 +64,6 @@ hazelcast-spring true - - com.hazelcast - hazelcast-client - test - com.sun.mail jakarta.mail diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/package-info.java index 58d63614e04..cf59117c4e0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/package-info.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/package-info.java @@ -15,6 +15,6 @@ */ /** - * Auto-configuration for Hazelcast's actuator. + * Auto-configuration for actuator Hazelcast concerns. */ package org.springframework.boot.actuate.autoconfigure.hazelcast; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationIntegrationTests.java index 8056ceef9b5..da8cb533b36 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationIntegrationTests.java @@ -16,11 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.hazelcast; -import com.hazelcast.client.config.ClientConfig; -import com.hazelcast.config.Config; -import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration; @@ -40,17 +36,10 @@ import static org.assertj.core.api.Assertions.assertThat; */ class HazelcastHealthIndicatorAutoConfigurationIntegrationTests { - private final HazelcastInstance hazelcastServer = Hazelcast.newHazelcastInstance(new Config()); - - private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withBean(ClientConfig.class) + private ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(HazelcastHealthIndicatorAutoConfiguration.class, HazelcastAutoConfiguration.class, HealthIndicatorAutoConfiguration.class)); - @AfterEach - void shutdown() { - this.hazelcastServer.shutdown(); - } - @Test void hazelcastUp() { this.contextRunner.run((context) -> { @@ -66,7 +55,7 @@ class HazelcastHealthIndicatorAutoConfigurationIntegrationTests { @Test void hazelcastDown() { this.contextRunner.run((context) -> { - shutdown(); + context.getBean(HazelcastInstance.class).shutdown(); assertThat(context).hasSingleBean(HazelcastHealthIndicator.class); Health health = context.getBean(HazelcastHealthIndicator.class).health(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationTests.java index a980c6db548..3e9e980776f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthIndicatorAutoConfigurationTests.java @@ -48,7 +48,6 @@ class HazelcastHealthIndicatorAutoConfigurationTests { void runWhenDisabledShouldNotCreateIndicator() { this.contextRunner.withPropertyValues("management.health.hazelcast.enabled:false") .run((context) -> assertThat(context).doesNotHaveBean(HazelcastHealthIndicator.class) - .doesNotHaveBean(HazelcastHealthIndicator.class) .hasSingleBean(ApplicationHealthIndicator.class)); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicator.java index 42d531b5d92..d2c23f3a736 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicator.java @@ -16,12 +16,7 @@ package org.springframework.boot.actuate.hazelcast; -import java.util.LinkedHashMap; -import java.util.Map; - -import com.hazelcast.core.Endpoint; import com.hazelcast.core.HazelcastInstance; -import com.hazelcast.transaction.TransactionalTask; import org.springframework.boot.actuate.health.AbstractHealthIndicator; import org.springframework.boot.actuate.health.Health; @@ -29,15 +24,14 @@ import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.util.Assert; /** - * {@link HealthIndicator} for a Hazelcast. + * {@link HealthIndicator} for Hazelcast. * * @author Dmytro Nosan + * @author Stephane Nicoll * @since 2.2.0 */ public class HazelcastHealthIndicator extends AbstractHealthIndicator { - private static final TransactionalTask TASK = (context) -> null; - private final HazelcastInstance hazelcast; public HazelcastHealthIndicator(HazelcastInstance hazelcast) { @@ -48,16 +42,11 @@ public class HazelcastHealthIndicator extends AbstractHealthIndicator { @Override protected void doHealthCheck(Health.Builder builder) { - this.hazelcast.executeTransaction(TASK); - builder.up().withDetails(getDetails()); - } - - private Map getDetails() { - Map details = new LinkedHashMap<>(); - Endpoint endpoint = this.hazelcast.getLocalEndpoint(); - details.put("name", this.hazelcast.getName()); - details.put("uuid", endpoint.getUuid()); - return details; + this.hazelcast.executeTransaction((context) -> { + builder.up().withDetail("name", this.hazelcast.getName()).withDetail("uuid", + this.hazelcast.getLocalEndpoint().getUuid()); + return null; + }); } } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicatorTests.java index a8dd1d2841a..1340e6058f5 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/hazelcast/HazelcastHealthIndicatorTests.java @@ -19,6 +19,7 @@ package org.springframework.boot.actuate.hazelcast; import com.hazelcast.core.Endpoint; import com.hazelcast.core.HazelcastException; import com.hazelcast.core.HazelcastInstance; +import com.hazelcast.transaction.TransactionalTask; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.health.Health; @@ -33,22 +34,23 @@ import static org.mockito.Mockito.mock; * Tests for {@link HazelcastHealthIndicator}. * * @author Dmytro Nosan + * @author Stephane Nicoll */ class HazelcastHealthIndicatorTests { private final HazelcastInstance hazelcast = mock(HazelcastInstance.class); - private final HazelcastHealthIndicator healthIndicator = new HazelcastHealthIndicator(this.hazelcast); - @Test void hazelcastUp() { Endpoint endpoint = mock(Endpoint.class); when(this.hazelcast.getName()).thenReturn("hz0-instance"); when(this.hazelcast.getLocalEndpoint()).thenReturn(endpoint); when(endpoint.getUuid()).thenReturn("7581bb2f-879f-413f-b574-0071d7519eb0"); - - Health health = this.healthIndicator.health(); - + when(this.hazelcast.executeTransaction(any())).thenAnswer((invocation) -> { + TransactionalTask task = invocation.getArgument(0); + return task.execute(null); + }); + Health health = new HazelcastHealthIndicator(this.hazelcast).health(); assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health.getDetails()).containsOnlyKeys("name", "uuid").containsEntry("name", "hz0-instance") .containsEntry("uuid", "7581bb2f-879f-413f-b574-0071d7519eb0"); @@ -57,9 +59,7 @@ class HazelcastHealthIndicatorTests { @Test void hazelcastDown() { when(this.hazelcast.executeTransaction(any())).thenThrow(new HazelcastException()); - - Health health = this.healthIndicator.health(); - + Health health = new HazelcastHealthIndicator(this.hazelcast).health(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); } diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc index 209e94f8053..24c1576c42d 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc @@ -764,6 +764,9 @@ The following `HealthIndicators` are auto-configured by Spring Boot when appropr |{sc-spring-boot-actuator}/elasticsearch/ElasticsearchHealthIndicator.{sc-ext}[`ElasticsearchHealthIndicator`] |Checks that an Elasticsearch cluster is up. +|{sc-spring-boot-actuator}/hazelcast/HazelcastHealthIndicator.{sc-ext}[`HazelcastHealthIndicator`] +|Checks that an Hazelcast server is up. + |{sc-spring-boot-actuator}/influx/InfluxDbHealthIndicator.{sc-ext}[`InfluxDbHealthIndicator`] |Checks that an InfluxDB server is up.