Consider performance standby mode in health check.

Extract common code to HealthBuilderDelegate.

Closes gh-367.
This commit is contained in:
Mark Paluch
2019-11-06 11:28:52 +01:00
parent 551d0f2761
commit 4f7ae02140
4 changed files with 112 additions and 50 deletions

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2018-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.cloud.vault.config;
import org.springframework.boot.actuate.health.Health;
import org.springframework.util.StringUtils;
import org.springframework.vault.support.VaultHealth;
/**
* Common delegate to transport health properties into the Health actuator
* {@link Health.Builder}.
*
* @author Mark Paluch
* @since 2.2
*/
final class HealthBuilderDelegate {
private HealthBuilderDelegate() {
}
static void contributeToHealth(VaultHealth healthResponse, Health.Builder builder) {
if (!healthResponse.isInitialized()) {
builder.down().withDetail("state", "Vault uninitialized");
}
else if (healthResponse.isSealed()) {
builder.down().withDetail("state", "Vault sealed");
}
else if (healthResponse.isStandby()) {
builder.up().withDetail("state", "Vault in standby");
}
else if (healthResponse.isPerformanceStandby()) {
builder.up().withDetail("state", "Vault in performance standby");
}
else if (healthResponse.isRecoveryReplicationSecondary()) {
builder.up().withDetail("state",
"Vault in recovery replication secondary mode");
}
else {
builder.up();
}
if (StringUtils.hasText(healthResponse.getVersion())) {
builder.withDetail("version", healthResponse.getVersion());
}
}
}

View File

@@ -18,7 +18,6 @@ package org.springframework.cloud.vault.config;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health.Builder;
import org.springframework.util.StringUtils;
import org.springframework.vault.core.VaultOperations;
import org.springframework.vault.support.VaultHealth;
@@ -40,23 +39,7 @@ public class VaultHealthIndicator extends AbstractHealthIndicator {
protected void doHealthCheck(Builder builder) {
VaultHealth vaultHealthResponse = this.vaultOperations.opsForSys().health();
if (!vaultHealthResponse.isInitialized()) {
builder.down().withDetail("state", "Vault uninitialized");
}
else if (vaultHealthResponse.isSealed()) {
builder.down().withDetail("state", "Vault sealed");
}
else if (vaultHealthResponse.isStandby()) {
builder.up().withDetail("state", "Vault in standby");
}
else {
builder.up();
}
if (StringUtils.hasText(vaultHealthResponse.getVersion())) {
builder.withDetail("version", vaultHealthResponse.getVersion());
}
HealthBuilderDelegate.contributeToHealth(vaultHealthResponse, builder);
}
}

View File

@@ -28,7 +28,6 @@ import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Health.Builder;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.vault.core.ReactiveVaultOperations;
import org.springframework.vault.support.VaultHealth;
import org.springframework.web.reactive.function.client.WebClientResponseException;
@@ -65,22 +64,7 @@ public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicato
private static Health getHealth(Builder builder,
VaultHealthImpl vaultHealthResponse) {
if (!vaultHealthResponse.isInitialized()) {
builder.withDetail("state", "Vault uninitialized");
}
else if (vaultHealthResponse.isSealed()) {
builder.down().withDetail("state", "Vault sealed");
}
else if (vaultHealthResponse.isStandby()) {
builder.up().withDetail("state", "Vault in standby");
}
else {
builder.up();
}
if (StringUtils.hasText(vaultHealthResponse.getVersion())) {
builder.withDetail("version", vaultHealthResponse.getVersion());
}
HealthBuilderDelegate.contributeToHealth(vaultHealthResponse, builder);
return builder.build();
}
@@ -96,7 +80,7 @@ public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicato
}
@JsonIgnoreProperties(ignoreUnknown = true)
private static final class VaultHealthImpl implements VaultHealth {
static class VaultHealthImpl implements VaultHealth {
private final boolean initialized;
@@ -104,20 +88,29 @@ public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicato
private final boolean standby;
private final boolean performanceStandby;
private final boolean replicationRecoverySecondary;
private final int serverTimeUtc;
@Nullable
private final String version;
private VaultHealthImpl(@JsonProperty("initialized") boolean initialized,
VaultHealthImpl(@JsonProperty("initialized") boolean initialized,
@JsonProperty("sealed") boolean sealed,
@JsonProperty("standby") boolean standby,
@JsonProperty("performance_standby") boolean performanceStandby,
@Nullable @JsonProperty("replication_dr_mode") String replicationRecoverySecondary,
@JsonProperty("server_time_utc") int serverTimeUtc,
@Nullable @JsonProperty("version") String version) {
this.initialized = initialized;
this.sealed = sealed;
this.standby = standby;
this.performanceStandby = performanceStandby;
this.replicationRecoverySecondary = replicationRecoverySecondary != null
&& !"disabled".equalsIgnoreCase(replicationRecoverySecondary);
this.serverTimeUtc = serverTimeUtc;
this.version = version;
}
@@ -134,6 +127,14 @@ public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicato
return this.standby;
}
public boolean isPerformanceStandby() {
return this.performanceStandby;
}
public boolean isRecoveryReplicationSecondary() {
return this.replicationRecoverySecondary;
}
public int getServerTimeUtc() {
return this.serverTimeUtc;
}
@@ -154,6 +155,8 @@ public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicato
VaultHealthImpl that = (VaultHealthImpl) o;
return this.initialized == that.initialized && this.sealed == that.sealed
&& this.standby == that.standby
&& this.performanceStandby == that.performanceStandby
&& this.replicationRecoverySecondary == that.replicationRecoverySecondary
&& this.serverTimeUtc == that.serverTimeUtc
&& Objects.equals(this.version, that.version);
}
@@ -161,22 +164,10 @@ public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicato
@Override
public int hashCode() {
return Objects.hash(this.initialized, this.sealed, this.standby,
this.performanceStandby, this.replicationRecoverySecondary,
this.serverTimeUtc, this.version);
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getClass().getSimpleName());
sb.append(" [initialized=").append(this.initialized);
sb.append(", sealed=").append(this.sealed);
sb.append(", standby=").append(this.standby);
sb.append(", serverTimeUtc=").append(this.serverTimeUtc);
sb.append(", version='").append(this.version).append('\'');
sb.append(']');
return sb.toString();
}
}
}

View File

@@ -115,4 +115,30 @@ public class VaultHealthIndicatorUnitTests {
assertThat(health.getDetails()).containsKey("error");
}
@Test
public void shouldReportPerformanceStandby() {
when(this.healthResponse.isInitialized()).thenReturn(true);
when(this.healthResponse.isPerformanceStandby()).thenReturn(true);
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails()).containsEntry("state",
"Vault in performance standby");
}
@Test
public void shouldReportRecoveryReplication() {
when(this.healthResponse.isInitialized()).thenReturn(true);
when(this.healthResponse.isRecoveryReplicationSecondary()).thenReturn(true);
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails()).containsEntry("state",
"Vault in recovery replication secondary mode");
}
}