Use server version from database in Neo4j health details
See gh-27294
This commit is contained in:
parent
8db63db564
commit
f7fd0ac527
|
|
@ -33,14 +33,13 @@ class Neo4jHealthDetailsHandler {
|
|||
/**
|
||||
* Add health details for the specified {@link ResultSummary} and {@code edition}.
|
||||
* @param builder the {@link Builder} to use
|
||||
* @param version the version of the server
|
||||
* @param edition the edition of the server
|
||||
* @param resultSummary server information
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
void addHealthDetails(Builder builder, String edition, ResultSummary resultSummary) {
|
||||
void addHealthDetails(Builder builder, String version, String edition, ResultSummary resultSummary) {
|
||||
ServerInfo serverInfo = resultSummary.server();
|
||||
builder.up().withDetail("server", serverInfo.version() + "@" + serverInfo.address()).withDetail("edition",
|
||||
edition);
|
||||
builder.up().withDetail("server", version + "@" + serverInfo.address()).withDetail("edition", edition);
|
||||
DatabaseInfo databaseInfo = resultSummary.database();
|
||||
if (StringUtils.hasText(databaseInfo.name())) {
|
||||
builder.withDetail("database", databaseInfo.name());
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
import org.neo4j.driver.AccessMode;
|
||||
import org.neo4j.driver.Driver;
|
||||
import org.neo4j.driver.Record;
|
||||
import org.neo4j.driver.Result;
|
||||
import org.neo4j.driver.Session;
|
||||
import org.neo4j.driver.SessionConfig;
|
||||
|
|
@ -46,7 +47,7 @@ public class Neo4jHealthIndicator extends AbstractHealthIndicator {
|
|||
/**
|
||||
* The Cypher statement used to verify Neo4j is up.
|
||||
*/
|
||||
static final String CYPHER = "CALL dbms.components() YIELD name, edition WHERE name = 'Neo4j Kernel' RETURN edition";
|
||||
static final String CYPHER = "CALL dbms.components() YIELD versions, name, edition WHERE name = 'Neo4j Kernel' RETURN edition, versions[0] as version";
|
||||
|
||||
/**
|
||||
* Message logged before retrying a health check.
|
||||
|
|
@ -91,9 +92,11 @@ public class Neo4jHealthIndicator extends AbstractHealthIndicator {
|
|||
// all possible workloads
|
||||
try (Session session = this.driver.session(DEFAULT_SESSION_CONFIG)) {
|
||||
Result result = session.run(CYPHER);
|
||||
String edition = result.single().get("edition").asString();
|
||||
Record record = result.single();
|
||||
String edition = record.get("edition").asString();
|
||||
String version = record.get("version").asString();
|
||||
ResultSummary resultSummary = result.consume();
|
||||
this.healthDetailsHandler.addHealthDetails(builder, edition, resultSummary);
|
||||
this.healthDetailsHandler.addHealthDetails(builder, version, edition, resultSummary);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.neo4j.driver.reactive.RxSession;
|
|||
import org.neo4j.driver.summary.ResultSummary;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuples;
|
||||
import reactor.util.retry.Retry;
|
||||
|
||||
import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator;
|
||||
|
|
@ -58,18 +59,21 @@ public final class Neo4jReactiveHealthIndicator extends AbstractReactiveHealthIn
|
|||
.doOnError(SessionExpiredException.class,
|
||||
(e) -> logger.warn(Neo4jHealthIndicator.MESSAGE_SESSION_EXPIRED))
|
||||
.retryWhen(Retry.max(1).filter(SessionExpiredException.class::isInstance)).map((result) -> {
|
||||
this.healthDetailsHandler.addHealthDetails(builder, result.getT1(), result.getT2());
|
||||
this.healthDetailsHandler.addHealthDetails(builder, result.getT1().getT1(), result.getT1().getT2(),
|
||||
result.getT2());
|
||||
return builder.build();
|
||||
});
|
||||
}
|
||||
|
||||
Mono<Tuple2<String, ResultSummary>> runHealthCheckQuery() {
|
||||
Mono<Tuple2<Tuple2<String, String>, ResultSummary>> runHealthCheckQuery() {
|
||||
// We use WRITE here to make sure UP is returned for a server that supports
|
||||
// all possible workloads
|
||||
return Mono.using(() -> this.driver.rxSession(Neo4jHealthIndicator.DEFAULT_SESSION_CONFIG), (session) -> {
|
||||
RxResult result = session.run(Neo4jHealthIndicator.CYPHER);
|
||||
return Mono.from(result.records()).map((record) -> record.get("edition").asString())
|
||||
.zipWhen((edition) -> Mono.from(result.consume()));
|
||||
return Mono.from(result.records())
|
||||
.flatMap((record) -> Mono
|
||||
.just(Tuples.of(record.get("version").asString(), record.get("edition").asString()))
|
||||
.zipWhen((edition) -> Mono.from(result.consume())));
|
||||
}, RxSession::close);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ class Neo4jHealthIndicatorTests {
|
|||
|
||||
@Test
|
||||
void neo4jIsUp() {
|
||||
ResultSummary resultSummary = ResultSummaryMock.createResultSummary("4711", "My Home", "test");
|
||||
Driver driver = mockDriver(resultSummary, "ultimate collectors edition");
|
||||
ResultSummary resultSummary = ResultSummaryMock.createResultSummary("My Home", "test");
|
||||
Driver driver = mockDriver(resultSummary, "4711", "ultimate collectors edition");
|
||||
Health health = new Neo4jHealthIndicator(driver).health();
|
||||
assertThat(health.getStatus()).isEqualTo(Status.UP);
|
||||
assertThat(health.getDetails()).containsEntry("server", "4711@My Home");
|
||||
|
|
@ -62,8 +62,8 @@ class Neo4jHealthIndicatorTests {
|
|||
|
||||
@Test
|
||||
void neo4jIsUpWithoutDatabaseName() {
|
||||
ResultSummary resultSummary = ResultSummaryMock.createResultSummary("4711", "My Home", null);
|
||||
Driver driver = mockDriver(resultSummary, "some edition");
|
||||
ResultSummary resultSummary = ResultSummaryMock.createResultSummary("My Home", null);
|
||||
Driver driver = mockDriver(resultSummary, "4711", "some edition");
|
||||
Health health = new Neo4jHealthIndicator(driver).health();
|
||||
assertThat(health.getStatus()).isEqualTo(Status.UP);
|
||||
assertThat(health.getDetails()).containsEntry("server", "4711@My Home");
|
||||
|
|
@ -73,8 +73,8 @@ class Neo4jHealthIndicatorTests {
|
|||
|
||||
@Test
|
||||
void neo4jIsUpWithEmptyDatabaseName() {
|
||||
ResultSummary resultSummary = ResultSummaryMock.createResultSummary("4711", "My Home", "");
|
||||
Driver driver = mockDriver(resultSummary, "some edition");
|
||||
ResultSummary resultSummary = ResultSummaryMock.createResultSummary("My Home", "");
|
||||
Driver driver = mockDriver(resultSummary, "4711", "some edition");
|
||||
Health health = new Neo4jHealthIndicator(driver).health();
|
||||
assertThat(health.getStatus()).isEqualTo(Status.UP);
|
||||
assertThat(health.getDetails()).containsEntry("server", "4711@My Home");
|
||||
|
|
@ -84,9 +84,9 @@ class Neo4jHealthIndicatorTests {
|
|||
|
||||
@Test
|
||||
void neo4jIsUpWithOneSessionExpiredException() {
|
||||
ResultSummary resultSummary = ResultSummaryMock.createResultSummary("4711", "My Home", "");
|
||||
ResultSummary resultSummary = ResultSummaryMock.createResultSummary("My Home", "");
|
||||
Session session = mock(Session.class);
|
||||
Result statementResult = mockStatementResult(resultSummary, "some edition");
|
||||
Result statementResult = mockStatementResult(resultSummary, "4711", "some edition");
|
||||
AtomicInteger count = new AtomicInteger();
|
||||
given(session.run(anyString())).will((invocation) -> {
|
||||
if (count.compareAndSet(0, 1)) {
|
||||
|
|
@ -112,17 +112,18 @@ class Neo4jHealthIndicatorTests {
|
|||
assertThat(health.getDetails()).containsKeys("error");
|
||||
}
|
||||
|
||||
private Result mockStatementResult(ResultSummary resultSummary, String edition) {
|
||||
private Result mockStatementResult(ResultSummary resultSummary, String version, String edition) {
|
||||
Record record = mock(Record.class);
|
||||
given(record.get("edition")).willReturn(Values.value(edition));
|
||||
given(record.get("version")).willReturn(Values.value(version));
|
||||
Result statementResult = mock(Result.class);
|
||||
given(statementResult.single()).willReturn(record);
|
||||
given(statementResult.consume()).willReturn(resultSummary);
|
||||
return statementResult;
|
||||
}
|
||||
|
||||
private Driver mockDriver(ResultSummary resultSummary, String edition) {
|
||||
Result statementResult = mockStatementResult(resultSummary, edition);
|
||||
private Driver mockDriver(ResultSummary resultSummary, String version, String edition) {
|
||||
Result statementResult = mockStatementResult(resultSummary, version, edition);
|
||||
Session session = mock(Session.class);
|
||||
given(session.run(anyString())).willReturn(statementResult);
|
||||
Driver driver = mock(Driver.class);
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ class Neo4jReactiveHealthIndicatorTests {
|
|||
|
||||
@Test
|
||||
void neo4jIsUp() {
|
||||
ResultSummary resultSummary = ResultSummaryMock.createResultSummary("4711", "My Home", "test");
|
||||
Driver driver = mockDriver(resultSummary, "ultimate collectors edition");
|
||||
ResultSummary resultSummary = ResultSummaryMock.createResultSummary("My Home", "test");
|
||||
Driver driver = mockDriver(resultSummary, "4711", "ultimate collectors edition");
|
||||
Neo4jReactiveHealthIndicator healthIndicator = new Neo4jReactiveHealthIndicator(driver);
|
||||
healthIndicator.health().as(StepVerifier::create).consumeNextWith((health) -> {
|
||||
assertThat(health.getStatus()).isEqualTo(Status.UP);
|
||||
|
|
@ -63,9 +63,9 @@ class Neo4jReactiveHealthIndicatorTests {
|
|||
|
||||
@Test
|
||||
void neo4jIsUpWithOneSessionExpiredException() {
|
||||
ResultSummary resultSummary = ResultSummaryMock.createResultSummary("4711", "My Home", "");
|
||||
ResultSummary resultSummary = ResultSummaryMock.createResultSummary("My Home", "");
|
||||
RxSession session = mock(RxSession.class);
|
||||
RxResult statementResult = mockStatementResult(resultSummary, "some edition");
|
||||
RxResult statementResult = mockStatementResult(resultSummary, "4711", "some edition");
|
||||
AtomicInteger count = new AtomicInteger();
|
||||
given(session.run(anyString())).will((invocation) -> {
|
||||
if (count.compareAndSet(0, 1)) {
|
||||
|
|
@ -95,17 +95,18 @@ class Neo4jReactiveHealthIndicatorTests {
|
|||
}).verifyComplete();
|
||||
}
|
||||
|
||||
private RxResult mockStatementResult(ResultSummary resultSummary, String edition) {
|
||||
private RxResult mockStatementResult(ResultSummary resultSummary, String version, String edition) {
|
||||
Record record = mock(Record.class);
|
||||
given(record.get("edition")).willReturn(Values.value(edition));
|
||||
given(record.get("version")).willReturn(Values.value(version));
|
||||
RxResult statementResult = mock(RxResult.class);
|
||||
given(statementResult.records()).willReturn(Mono.just(record));
|
||||
given(statementResult.consume()).willReturn(Mono.just(resultSummary));
|
||||
return statementResult;
|
||||
}
|
||||
|
||||
private Driver mockDriver(ResultSummary resultSummary, String edition) {
|
||||
RxResult statementResult = mockStatementResult(resultSummary, edition);
|
||||
private Driver mockDriver(ResultSummary resultSummary, String version, String edition) {
|
||||
RxResult statementResult = mockStatementResult(resultSummary, version, edition);
|
||||
RxSession session = mock(RxSession.class);
|
||||
given(session.run(anyString())).willReturn(statementResult);
|
||||
Driver driver = mock(Driver.class);
|
||||
|
|
|
|||
|
|
@ -33,10 +33,8 @@ final class ResultSummaryMock {
|
|||
private ResultSummaryMock() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
static ResultSummary createResultSummary(String serverVersion, String serverAddress, String databaseName) {
|
||||
static ResultSummary createResultSummary(String serverAddress, String databaseName) {
|
||||
ServerInfo serverInfo = mock(ServerInfo.class);
|
||||
given(serverInfo.version()).willReturn(serverVersion);
|
||||
given(serverInfo.address()).willReturn(serverAddress);
|
||||
DatabaseInfo databaseInfo = mock(DatabaseInfo.class);
|
||||
given(databaseInfo.name()).willReturn(databaseName);
|
||||
|
|
|
|||
Loading…
Reference in New Issue