Polishing
Reformat code. Use state key for health indicator details. Add health method declaration to VaultOperations. Switch actuator dependency to optional dependency. Add tests. Original pull request: gh-29 Fixes gh-24
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -39,7 +39,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
@ConditionalOnExpression("${health.vault.enabled:true}")
|
||||
@AutoConfigureBefore({ EndpointAutoConfiguration.class })
|
||||
@AutoConfigureAfter({ HealthIndicatorAutoConfiguration.class })
|
||||
public class VaultConfigBootstrapHealthIndicator{
|
||||
public class VaultConfigBootstrapHealthIndicator {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "vaultHealthIndicator")
|
||||
public HealthIndicator vaultHealthIndicator() {
|
||||
|
||||
@@ -24,27 +24,34 @@ import org.springframework.cloud.vault.VaultHealthResponse;
|
||||
* @author Stuart Ingram
|
||||
*/
|
||||
public class VaultHealthIndicator implements HealthIndicator {
|
||||
|
||||
@Autowired
|
||||
private VaultTemplate vaultTemplate;
|
||||
|
||||
@Override
|
||||
public Health health() {
|
||||
|
||||
try {
|
||||
|
||||
VaultHealthResponse vaultHealthResponse = vaultTemplate.health();
|
||||
if(!vaultHealthResponse.isInitialized()) {
|
||||
return Health.down().withDetail("Vault uninitialized",null).build();
|
||||
} else if (vaultHealthResponse.isSealed()) {
|
||||
return Health.down().withDetail("Vault sealed",null).build();
|
||||
} else if (vaultHealthResponse.isStandby()) {
|
||||
return Health.outOfService().withDetail("Vault in standby",null).build();
|
||||
} else {
|
||||
return Health.up().build();
|
||||
|
||||
if (!vaultHealthResponse.isInitialized()) {
|
||||
return Health.down().withDetail("state", "Vault uninitialized").build();
|
||||
}
|
||||
|
||||
if (vaultHealthResponse.isSealed()) {
|
||||
return Health.down().withDetail("state", "Vault sealed").build();
|
||||
}
|
||||
|
||||
if (vaultHealthResponse.isStandby()) {
|
||||
return Health.outOfService().withDetail("state", "Vault in standby").build();
|
||||
}
|
||||
|
||||
return Health.up().build();
|
||||
}
|
||||
catch(Exception e) {
|
||||
catch (Exception e) {
|
||||
return Health.down().build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.vault.VaultClientResponse;
|
||||
import org.springframework.cloud.vault.VaultHealthResponse;
|
||||
|
||||
/**
|
||||
* Interface that specified a basic set of Vault operations, implemented by
|
||||
@@ -57,6 +58,13 @@ public interface VaultOperations {
|
||||
<T> T doWithVault(String pathTemplate, Map<String, ?> variables,
|
||||
SessionCallback sessionCallback);
|
||||
|
||||
/**
|
||||
* Query the current Vault service for it's health status.
|
||||
*
|
||||
* @return A {@link VaultHealthResponse} containing the current service status.
|
||||
*/
|
||||
VaultHealthResponse health();
|
||||
|
||||
/**
|
||||
* Callback to execute actions within an authenticated {@link VaultSession}.
|
||||
*
|
||||
|
||||
@@ -35,6 +35,8 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class VaultTemplate implements InitializingBean, VaultOperations {
|
||||
|
||||
private final static String HEALTH_URL_TEMPLATE = "sys/health";
|
||||
|
||||
private final VaultProperties properties;
|
||||
private final VaultClient client;
|
||||
private final ClientAuthentication clientAuthentication;
|
||||
@@ -100,7 +102,7 @@ public class VaultTemplate implements InitializingBean, VaultOperations {
|
||||
|
||||
Assert.notNull(sessionCallback, "SessionCallback must not be null!");
|
||||
|
||||
URI uri = client.buildUri(properties, path);
|
||||
URI uri = VaultClient.buildUri(properties, path);
|
||||
return sessionCallback.doWithVault(uri, vaultSession);
|
||||
}
|
||||
|
||||
@@ -114,29 +116,10 @@ public class VaultTemplate implements InitializingBean, VaultOperations {
|
||||
return sessionCallback.doWithVault(uri, vaultSession);
|
||||
}
|
||||
|
||||
private final static String HEALTH_URL_TEMPLATE = "sys/health";
|
||||
|
||||
/**
|
||||
* Query the current Vault service for it's health status
|
||||
*
|
||||
* @return A {@link VaultHealthResponse} containing the current service status.
|
||||
*/
|
||||
@Override
|
||||
public VaultHealthResponse health() {
|
||||
URI uri = client.buildUri(properties, HEALTH_URL_TEMPLATE);
|
||||
|
||||
URI uri = VaultClient.buildUri(properties, HEALTH_URL_TEMPLATE);
|
||||
return client.health(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether Vault is available (vault created and unsealed).
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isAvailable() {
|
||||
try{
|
||||
VaultHealthResponse health = health();
|
||||
return health.isInitialized() && !health.isSealed();
|
||||
} catch(Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2016 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.cloud.vault.config;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.cloud.vault.VaultHealthResponse;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class VaultHealthIndicatorUnitTests {
|
||||
|
||||
@InjectMocks
|
||||
VaultHealthIndicator healthIndicator = new VaultHealthIndicator();
|
||||
|
||||
@Mock
|
||||
VaultTemplate vaultTemplate;
|
||||
|
||||
@Test
|
||||
public void shouldReportHealthyService() throws Exception {
|
||||
|
||||
VaultHealthResponse healthResponse = new VaultHealthResponse();
|
||||
healthResponse.setInitialized(true);
|
||||
|
||||
when(vaultTemplate.health()).thenReturn(healthResponse);
|
||||
|
||||
Health health = healthIndicator.health();
|
||||
assertThat(health.getStatus()).isEqualTo(Status.UP);
|
||||
assertThat(health.getDetails()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReportSealedService() throws Exception {
|
||||
|
||||
VaultHealthResponse healthResponse = new VaultHealthResponse();
|
||||
healthResponse.setInitialized(true);
|
||||
healthResponse.setSealed(true);
|
||||
|
||||
when(vaultTemplate.health()).thenReturn(healthResponse);
|
||||
|
||||
Health health = healthIndicator.health();
|
||||
|
||||
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
|
||||
assertThat(health.getDetails()).containsEntry("state", "Vault sealed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReportUninitializedService() throws Exception {
|
||||
|
||||
VaultHealthResponse healthResponse = new VaultHealthResponse();
|
||||
|
||||
when(vaultTemplate.health()).thenReturn(healthResponse);
|
||||
|
||||
Health health = healthIndicator.health();
|
||||
|
||||
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
|
||||
assertThat(health.getDetails()).containsEntry("state", "Vault uninitialized");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReportStandbyService() throws Exception {
|
||||
|
||||
VaultHealthResponse healthResponse = new VaultHealthResponse();
|
||||
healthResponse.setInitialized(true);
|
||||
healthResponse.setStandby(true);
|
||||
|
||||
when(vaultTemplate.health()).thenReturn(healthResponse);
|
||||
|
||||
Health health = healthIndicator.health();
|
||||
|
||||
assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE);
|
||||
assertThat(health.getDetails()).containsEntry("state", "Vault in standby");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exceptionsShouldReportDownStatus() throws Exception {
|
||||
|
||||
when(vaultTemplate.health()).thenThrow(new IllegalStateException());
|
||||
|
||||
Health health = healthIndicator.health();
|
||||
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
|
||||
assertThat(health.getDetails()).isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -21,16 +21,18 @@ import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Value object to bind HTTP API responses for sys/health
|
||||
* Value object to bind HTTP API responses for sys/health.
|
||||
*
|
||||
* @author Stuart Ingram
|
||||
* @author Bill Koch
|
||||
*/
|
||||
@Data
|
||||
public class VaultHealthResponse {
|
||||
|
||||
private boolean initialized;
|
||||
private boolean sealed;
|
||||
private boolean standby;
|
||||
|
||||
@JsonProperty("server_time_utc")
|
||||
private int serverTimeUtc;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user