Use ReactiveVaultSysOperations.health() for health check.

Closes gh-755
This commit is contained in:
Mark Paluch
2025-06-12 09:12:14 +02:00
parent 389217f67b
commit bad6add59f

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2021 the original author or authors.
* Copyright 2018-2025 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.
@@ -16,22 +16,12 @@
package org.springframework.cloud.vault.config;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import reactor.core.publisher.Mono;
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.vault.client.VaultHttpHeaders;
import org.springframework.vault.core.ReactiveVaultOperations;
import org.springframework.vault.support.JacksonCompat;
import org.springframework.vault.support.VaultHealth;
import org.springframework.web.reactive.function.client.WebClientResponseException;
/**
* Reactive health indicator reporting Vault's availability.
@@ -47,124 +37,14 @@ public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicato
this.vaultOperations = vaultOperations;
}
@SuppressWarnings("BlockingMethodInNonBlockingContext")
private static Mono<? extends VaultHealthImpl> deserializeError(WebClientResponseException e) {
try {
JacksonCompat.ObjectMapperAccessor mapper = JacksonCompat.instance().getObjectMapperAccessor();
// Response is already materialized so not blocking here.
return Mono.just(mapper.deserialize(e.getResponseBodyAsByteArray(), VaultHealthImpl.class));
}
catch (Exception jsonError) {
UndeclaredThrowableException t = new UndeclaredThrowableException(jsonError);
t.addSuppressed(e);
return Mono.error(t);
}
}
private static Health getHealth(Builder builder, VaultHealthImpl vaultHealthResponse) {
HealthBuilderDelegate.contributeToHealth(vaultHealthResponse, builder);
return builder.build();
}
@Override
protected Mono<Health> doHealthCheck(Builder builder) {
return this.vaultOperations
.doWithVault((it) -> it.get()
.uri("sys/health")
.header(VaultHttpHeaders.VAULT_NAMESPACE, "")
.retrieve()
.bodyToMono(VaultHealthImpl.class))
.onErrorResume(WebClientResponseException.class, VaultReactiveHealthIndicator::deserializeError)
.map((vaultHealthResponse) -> getHealth(builder, vaultHealthResponse));
}
@JsonIgnoreProperties(ignoreUnknown = true)
static class VaultHealthImpl implements VaultHealth {
private final boolean initialized;
private final boolean sealed;
private final boolean standby;
private final boolean performanceStandby;
private final boolean replicationRecoverySecondary;
private final int serverTimeUtc;
@Nullable
private final String version;
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;
}
public boolean isInitialized() {
return this.initialized;
}
public boolean isSealed() {
return this.sealed;
}
public boolean isStandby() {
return this.standby;
}
public boolean isPerformanceStandby() {
return this.performanceStandby;
}
public boolean isRecoveryReplicationSecondary() {
return this.replicationRecoverySecondary;
}
public int getServerTimeUtc() {
return this.serverTimeUtc;
}
@Nullable
public String getVersion() {
return this.version;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof VaultHealthImpl)) {
return false;
}
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);
}
@Override
public int hashCode() {
return Objects.hash(this.initialized, this.sealed, this.standby, this.performanceStandby,
this.replicationRecoverySecondary, this.serverTimeUtc, this.version);
}
return this.vaultOperations.opsForSys().health().map((vaultHealthResponse) -> {
HealthBuilderDelegate.contributeToHealth(vaultHealthResponse, builder);
return builder.build();
});
}
}