Support Mongo's Stable API in MongoHealthIndicator

Closes gh-30849
This commit is contained in:
Madhura Bhave 2022-09-15 14:07:47 -07:00
parent 7f5785182d
commit b44a7e242c
6 changed files with 30 additions and 16 deletions

View File

@ -43,8 +43,8 @@ public class MongoHealthIndicator extends AbstractHealthIndicator {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
Document result = this.mongoTemplate.executeCommand("{ buildInfo: 1 }");
builder.up().withDetail("version", result.getString("version"));
Document result = this.mongoTemplate.executeCommand("{ isMaster: 1 }");
builder.up().withDetail("maxWireVersion", result.getInteger("maxWireVersion"));
}
}

View File

@ -43,12 +43,12 @@ public class MongoReactiveHealthIndicator extends AbstractReactiveHealthIndicato
@Override
protected Mono<Health> doHealthCheck(Health.Builder builder) {
Mono<Document> buildInfo = this.reactiveMongoTemplate.executeCommand("{ buildInfo: 1 }");
Mono<Document> buildInfo = this.reactiveMongoTemplate.executeCommand("{ isMaster: 1 }");
return buildInfo.map((document) -> up(builder, document));
}
private Health up(Health.Builder builder, Document document) {
return builder.up().withDetail("version", document.getString("version")).build();
return builder.up().withDetail("maxWireVersion", document.getInteger("maxWireVersion")).build();
}
}

View File

@ -40,26 +40,26 @@ class MongoHealthIndicatorTests {
@Test
void mongoIsUp() {
Document commandResult = mock(Document.class);
given(commandResult.getString("version")).willReturn("2.6.4");
given(commandResult.getInteger("maxWireVersion")).willReturn(10);
MongoTemplate mongoTemplate = mock(MongoTemplate.class);
given(mongoTemplate.executeCommand("{ buildInfo: 1 }")).willReturn(commandResult);
given(mongoTemplate.executeCommand("{ isMaster: 1 }")).willReturn(commandResult);
MongoHealthIndicator healthIndicator = new MongoHealthIndicator(mongoTemplate);
Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails().get("version")).isEqualTo("2.6.4");
then(commandResult).should().getString("version");
then(mongoTemplate).should().executeCommand("{ buildInfo: 1 }");
assertThat(health.getDetails().get("maxWireVersion")).isEqualTo(10);
then(commandResult).should().getInteger("maxWireVersion");
then(mongoTemplate).should().executeCommand("{ isMaster: 1 }");
}
@Test
void mongoIsDown() {
MongoTemplate mongoTemplate = mock(MongoTemplate.class);
given(mongoTemplate.executeCommand("{ buildInfo: 1 }")).willThrow(new MongoException("Connection failed"));
given(mongoTemplate.executeCommand("{ isMaster: 1 }")).willThrow(new MongoException("Connection failed"));
MongoHealthIndicator healthIndicator = new MongoHealthIndicator(mongoTemplate);
Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
assertThat((String) health.getDetails().get("error")).contains("Connection failed");
then(mongoTemplate).should().executeCommand("{ buildInfo: 1 }");
then(mongoTemplate).should().executeCommand("{ isMaster: 1 }");
}
}

View File

@ -41,23 +41,23 @@ class MongoReactiveHealthIndicatorTests {
@Test
void testMongoIsUp() {
Document buildInfo = mock(Document.class);
given(buildInfo.getString("version")).willReturn("2.6.4");
given(buildInfo.getInteger("maxWireVersion")).willReturn(10);
ReactiveMongoTemplate reactiveMongoTemplate = mock(ReactiveMongoTemplate.class);
given(reactiveMongoTemplate.executeCommand("{ buildInfo: 1 }")).willReturn(Mono.just(buildInfo));
given(reactiveMongoTemplate.executeCommand("{ isMaster: 1 }")).willReturn(Mono.just(buildInfo));
MongoReactiveHealthIndicator mongoReactiveHealthIndicator = new MongoReactiveHealthIndicator(
reactiveMongoTemplate);
Mono<Health> health = mongoReactiveHealthIndicator.health();
StepVerifier.create(health).consumeNextWith((h) -> {
assertThat(h.getStatus()).isEqualTo(Status.UP);
assertThat(h.getDetails()).containsOnlyKeys("version");
assertThat(h.getDetails().get("version")).isEqualTo("2.6.4");
assertThat(h.getDetails()).containsOnlyKeys("maxWireVersion");
assertThat(h.getDetails().get("maxWireVersion")).isEqualTo(10);
}).verifyComplete();
}
@Test
void testMongoIsDown() {
ReactiveMongoTemplate reactiveMongoTemplate = mock(ReactiveMongoTemplate.class);
given(reactiveMongoTemplate.executeCommand("{ buildInfo: 1 }"))
given(reactiveMongoTemplate.executeCommand("{ isMaster: 1 }"))
.willThrow(new MongoException("Connection failed"));
MongoReactiveHealthIndicator mongoReactiveHealthIndicator = new MongoReactiveHealthIndicator(
reactiveMongoTemplate);

View File

@ -1,3 +1,4 @@
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
spring.security.user.name=user
spring.security.user.password=password

View File

@ -29,6 +29,7 @@ import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
@ -53,6 +54,9 @@ public class SampleSessionMongoApplicationTests {
@Autowired
private TestRestTemplate restTemplate;
@LocalServerPort
private int port;
@Container
static MongoDBContainer mongo = new MongoDBContainer(DockerImageNames.mongo()).withStartupAttempts(3)
.withStartupTimeout(Duration.ofMinutes(2));
@ -73,6 +77,15 @@ public class SampleSessionMongoApplicationTests {
assertThat(sessions.size()).isEqualTo(1);
}
@Test
@SuppressWarnings("unchecked")
void health() {
ResponseEntity<String> entity = this.restTemplate
.getForEntity("http://localhost:" + this.port + "/actuator/health", String.class);
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
assertThat(entity.getBody()).contains("maxWireVersion");
}
private void createSession(URI uri) {
RequestEntity<Object> request = getRequestEntity(uri);
this.restTemplate.exchange(request, String.class);