diff --git a/spring-geode-actuator/src/main/java/org/springframework/geode/boot/actuate/GeodeDiskStoresHealthIndicator.java b/spring-geode-actuator/src/main/java/org/springframework/geode/boot/actuate/GeodeDiskStoresHealthIndicator.java index 70c1571b..21ff10c2 100644 --- a/spring-geode-actuator/src/main/java/org/springframework/geode/boot/actuate/GeodeDiskStoresHealthIndicator.java +++ b/spring-geode-actuator/src/main/java/org/springframework/geode/boot/actuate/GeodeDiskStoresHealthIndicator.java @@ -16,8 +16,6 @@ package org.springframework.geode.boot.actuate; -import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; - import java.io.File; import java.util.Arrays; import java.util.Collections; @@ -31,6 +29,7 @@ import org.apache.shiro.util.Assert; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.context.ApplicationContext; +import org.springframework.data.gemfire.util.ArrayUtils; import org.springframework.geode.boot.actuate.health.AbstractGeodeHealthIndicator; /** @@ -102,11 +101,11 @@ public class GeodeDiskStoresHealthIndicator extends AbstractGeodeHealthIndicator String diskStoreName = diskStore.getName(); - builder.withDetail(diskStoreKey(diskStoreName, "allow-force-compaction"), diskStore.getAllowForceCompaction()) - .withDetail(diskStoreKey(diskStoreName, "auto-compact"), diskStore.getAutoCompact()) + builder.withDetail(diskStoreKey(diskStoreName, "allow-force-compaction"), toYesNoString(diskStore.getAllowForceCompaction())) + .withDetail(diskStoreKey(diskStoreName, "auto-compact"), toYesNoString(diskStore.getAutoCompact())) .withDetail(diskStoreKey(diskStoreName, "compaction-threshold"), diskStore.getCompactionThreshold()) .withDetail(diskStoreKey(diskStoreName, "disk-directories"), toFilePathnamesString(diskStore.getDiskDirs())) - .withDetail(diskStoreKey(diskStoreName, "disk-directory-sizes"), Arrays.toString(diskStore.getDiskDirSizes())) + .withDetail(diskStoreKey(diskStoreName, "disk-directory-sizes"), Arrays.toString(nullSafeArray(diskStore.getDiskDirSizes()))) .withDetail(diskStoreKey(diskStoreName, "disk-usage-critical-percentage"), diskStore.getDiskUsageCriticalPercentage()) .withDetail(diskStoreKey(diskStoreName, "disk-usage-warning-percentage"), diskStore.getDiskUsageWarningPercentage()) .withDetail(diskStoreKey(diskStoreName, "max-oplog-size"), diskStore.getMaxOplogSize()) @@ -124,16 +123,20 @@ public class GeodeDiskStoresHealthIndicator extends AbstractGeodeHealthIndicator builder.unknown(); } + private String diskStoreKey(String diskStoreName, String suffix) { + return String.format("geode.disk-store.%1$s.%2$s", diskStoreName, suffix); + } + + private int[] nullSafeArray(int[] array) { + return array != null ? array : new int[0]; + } + private String toFilePathnamesString(File... files) { - return Arrays.toString(Arrays.stream(nullSafeArray(files, File.class)) + return Arrays.toString(Arrays.stream(ArrayUtils.nullSafeArray(files, File.class)) .filter(Objects::nonNull) .map(File::getAbsolutePath) .collect(Collectors.toSet()) .toArray()); } - - private String diskStoreKey(String diskStoreName, String suffix) { - return String.format("geode.disk-store.%1$s.%2$s", diskStoreName, suffix); - } } diff --git a/spring-geode-actuator/src/test/java/org/springframework/geode/boot/actuate/GeodeDiskStoresHealthIndicatorUnitTests.java b/spring-geode-actuator/src/test/java/org/springframework/geode/boot/actuate/GeodeDiskStoresHealthIndicatorUnitTests.java new file mode 100644 index 00000000..124ccba4 --- /dev/null +++ b/spring-geode-actuator/src/test/java/org/springframework/geode/boot/actuate/GeodeDiskStoresHealthIndicatorUnitTests.java @@ -0,0 +1,151 @@ +/* + * 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.apache.geode.cache.DiskStore; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.Status; +import org.springframework.context.ApplicationContext; +import org.springframework.data.gemfire.tests.mock.DiskStoreMockObjects; +import org.springframework.data.gemfire.util.ArrayUtils; + +/** + * Unit tests for {@link GeodeDiskStoresHealthIndicator}. + * + * @author John Blum + * @see org.junit.Test + * @see org.mockito.Mock + * @see org.mockito.Mockito + * @see org.mockito.junit.MockitoJUnitRunner + * @see org.apache.geode.cache.DiskStore + * @see org.springframework.boot.actuate.health.Health + * @see org.springframework.boot.actuate.health.HealthIndicator + * @see org.springframework.context.ApplicationContext + * @see org.springframework.geode.boot.actuate.GeodeDiskStoresHealthIndicator + * @since 1.0.0 + */ +@RunWith(MockitoJUnitRunner.class) +public class GeodeDiskStoresHealthIndicatorUnitTests { + + @Mock + private ApplicationContext mockApplicationContext; + + private GeodeDiskStoresHealthIndicator diskStoresHealthIndicator; + + @Before + public void setup() { + this.diskStoresHealthIndicator = new GeodeDiskStoresHealthIndicator(this.mockApplicationContext); + } + + @Test + public void healthCheckCapturesDetails() throws Exception { + + File mockDirectoryOne = mock(File.class); + File mockDirectoryTwo = mock(File.class); + + when(mockDirectoryOne.getAbsolutePath()).thenReturn("/ext/gemfire/disk/stores/one"); + when(mockDirectoryTwo.getAbsolutePath()).thenReturn("/ext/gemfire/disk/stores/two"); + + int[] diskDirectorySizes = { 1024, 8192 }; + + Map diskStoreBeans = new HashMap<>(); + + diskStoreBeans.put("MockDiskStoreOne", DiskStoreMockObjects.mockDiskStore("MockDiskStoreOne", + true, true, 90, + ArrayUtils.asArray(mockDirectoryOne, mockDirectoryTwo), diskDirectorySizes, 0.95f, + 0.90f, 1024000L, 16384, 5000L, 32768)); + + diskStoreBeans.put("MockDiskStoreTwo", DiskStoreMockObjects.mockDiskStore("MockDiskStoreTwo", + false, true, 50,null, null, + 0.90f,0.80f, 2048000L, 4096, + 15000L, 8192)); + + when(this.mockApplicationContext.getBeansOfType(DiskStore.class)).thenReturn(diskStoreBeans); + + Health.Builder builder = new Health.Builder(); + + this.diskStoresHealthIndicator.doHealthCheck(builder); + + Health health = builder.build(); + + assertThat(health).isNotNull(); + assertThat(health.getStatus()).isEqualTo(Status.UP); + + Map healthDetails = health.getDetails(); + + assertThat(healthDetails).isNotNull(); + assertThat(healthDetails).isNotEmpty(); + assertThat(healthDetails).containsEntry("geode.disk-store.count", diskStoreBeans.size()); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreOne.allow-force-compaction", "Yes"); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreOne.auto-compact", "Yes"); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreOne.compaction-threshold", 90); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreOne.disk-directories", "[/ext/gemfire/disk/stores/one, /ext/gemfire/disk/stores/two]"); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreOne.disk-directory-sizes", "[1024, 8192]"); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreOne.disk-usage-critical-percentage", 0.95f); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreOne.disk-usage-warning-percentage", 0.90f); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreOne.max-oplog-size", 1024000L); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreOne.queue-size", 16384); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreOne.time-interval", 5000L); + assertThat(healthDetails).containsKey("geode.disk-store.MockDiskStoreOne.uuid"); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreOne.write-buffer-size", 32768); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreTwo.allow-force-compaction", "No"); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreTwo.auto-compact", "Yes"); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreTwo.compaction-threshold", 50); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreTwo.disk-directories", "[]"); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreTwo.disk-directory-sizes", "[]"); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreTwo.disk-usage-critical-percentage", 0.90f); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreTwo.disk-usage-warning-percentage", 0.80f); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreTwo.max-oplog-size", 2048000L); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreTwo.queue-size", 4096); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreTwo.time-interval", 15000L); + assertThat(healthDetails).containsKey("geode.disk-store.MockDiskStoreOne.uuid"); + assertThat(healthDetails).containsEntry("geode.disk-store.MockDiskStoreTwo.write-buffer-size", 8192); + + verify(this.mockApplicationContext, times(1)).getBeansOfType(eq(DiskStore.class)); + } + + @Test + public void healthCheckFailsWhenNoApplcationContextIsPresent() throws Exception { + + GeodeDiskStoresHealthIndicator healthIndicator = new GeodeDiskStoresHealthIndicator(); + + Health.Builder builder = new Health.Builder(); + + healthIndicator.doHealthCheck(builder); + + Health health = builder.build(); + + assertThat(health).isNotNull(); + assertThat(health.getStatus()).isEqualTo(Status.UNKNOWN); + } +}