Commit 01272fa0 authored by Stephane Nicoll's avatar Stephane Nicoll

Polish "Add health indicator for Neo4j"

Closes gh-9557
parent 4c97dcb5
...@@ -105,8 +105,8 @@ import org.springframework.mail.javamail.JavaMailSenderImpl; ...@@ -105,8 +105,8 @@ import org.springframework.mail.javamail.JavaMailSenderImpl;
JestAutoConfiguration.class, JmsAutoConfiguration.class, JestAutoConfiguration.class, JmsAutoConfiguration.class,
LdapDataAutoConfiguration.class, MailSenderAutoConfiguration.class, LdapDataAutoConfiguration.class, MailSenderAutoConfiguration.class,
MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, MongoAutoConfiguration.class, MongoDataAutoConfiguration.class,
RabbitAutoConfiguration.class, RedisAutoConfiguration.class, Neo4jDataAutoConfiguration.class, RabbitAutoConfiguration.class,
SolrAutoConfiguration.class, Neo4jDataAutoConfiguration.class }) RedisAutoConfiguration.class, SolrAutoConfiguration.class })
@EnableConfigurationProperties({ HealthIndicatorProperties.class }) @EnableConfigurationProperties({ HealthIndicatorProperties.class })
@Import({ @Import({
ElasticsearchHealthIndicatorConfiguration.ElasticsearchClientHealthIndicatorConfiguration.class, ElasticsearchHealthIndicatorConfiguration.ElasticsearchClientHealthIndicatorConfiguration.class,
...@@ -261,6 +261,27 @@ public class HealthIndicatorAutoConfiguration { ...@@ -261,6 +261,27 @@ public class HealthIndicatorAutoConfiguration {
} }
@Configuration
@ConditionalOnBean(MongoTemplate.class)
@ConditionalOnEnabledHealthIndicator("mongo")
public static class MongoHealthIndicatorConfiguration extends
CompositeHealthIndicatorConfiguration<MongoHealthIndicator, MongoTemplate> {
private final Map<String, MongoTemplate> mongoTemplates;
public MongoHealthIndicatorConfiguration(
Map<String, MongoTemplate> mongoTemplates) {
this.mongoTemplates = mongoTemplates;
}
@Bean
@ConditionalOnMissingBean(name = "mongoHealthIndicator")
public HealthIndicator mongoHealthIndicator() {
return createHealthIndicator(this.mongoTemplates);
}
}
@Configuration @Configuration
@ConditionalOnClass(SessionFactory.class) @ConditionalOnClass(SessionFactory.class)
@ConditionalOnBean(SessionFactory.class) @ConditionalOnBean(SessionFactory.class)
...@@ -283,27 +304,6 @@ public class HealthIndicatorAutoConfiguration { ...@@ -283,27 +304,6 @@ public class HealthIndicatorAutoConfiguration {
} }
@Configuration
@ConditionalOnBean(MongoTemplate.class)
@ConditionalOnEnabledHealthIndicator("mongo")
public static class MongoHealthIndicatorConfiguration extends
CompositeHealthIndicatorConfiguration<MongoHealthIndicator, MongoTemplate> {
private final Map<String, MongoTemplate> mongoTemplates;
public MongoHealthIndicatorConfiguration(
Map<String, MongoTemplate> mongoTemplates) {
this.mongoTemplates = mongoTemplates;
}
@Bean
@ConditionalOnMissingBean(name = "mongoHealthIndicator")
public HealthIndicator mongoHealthIndicator() {
return createHealthIndicator(this.mongoTemplates);
}
}
@Configuration @Configuration
@ConditionalOnBean(RedisConnectionFactory.class) @ConditionalOnBean(RedisConnectionFactory.class)
@ConditionalOnEnabledHealthIndicator("redis") @ConditionalOnEnabledHealthIndicator("redis")
......
...@@ -23,23 +23,21 @@ import org.neo4j.ogm.model.Result; ...@@ -23,23 +23,21 @@ import org.neo4j.ogm.model.Result;
import org.neo4j.ogm.session.Session; import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory; import org.neo4j.ogm.session.SessionFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
/** /**
* {@link HealthIndicator} that tests the status of a Neo4j by executing a Cypher * {@link HealthIndicator} that tests the status of a Neo4j by executing a Cypher
* statement. * statement.
* *
* @author Eric Spiegelberg * @author Eric Spiegelberg
* @since 2.0.0
*/ */
@ConfigurationProperties(prefix = "management.health.neo4j", ignoreUnknownFields = false)
public class Neo4jHealthIndicator extends AbstractHealthIndicator { public class Neo4jHealthIndicator extends AbstractHealthIndicator {
private final SessionFactory sessionFactory;
/** /**
* The Cypher statement used to verify Neo4j is up. * The Cypher statement used to verify Neo4j is up.
*/ */
public static final String CYPHER = "match (n) return count(n) as nodes"; static final String CYPHER = "match (n) return count(n) as nodes";
private final SessionFactory sessionFactory;
/** /**
* Create a new {@link Neo4jHealthIndicator} using the specified * Create a new {@link Neo4jHealthIndicator} using the specified
...@@ -54,7 +52,7 @@ public class Neo4jHealthIndicator extends AbstractHealthIndicator { ...@@ -54,7 +52,7 @@ public class Neo4jHealthIndicator extends AbstractHealthIndicator {
protected void doHealthCheck(Health.Builder builder) throws Exception { protected void doHealthCheck(Health.Builder builder) throws Exception {
Session session = this.sessionFactory.openSession(); Session session = this.sessionFactory.openSession();
Result result = session.query(CYPHER, Collections.emptyMap()); Result result = session.query(CYPHER, Collections.EMPTY_MAP);
Iterable<Map<String, Object>> results = result.queryResults(); Iterable<Map<String, Object>> results = result.queryResults();
int nodes = (int) results.iterator().next().get("nodes"); int nodes = (int) results.iterator().next().get("nodes");
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
package org.springframework.boot.actuate.health; package org.springframework.boot.actuate.health;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -37,60 +38,49 @@ import static org.mockito.Mockito.mock; ...@@ -37,60 +38,49 @@ import static org.mockito.Mockito.mock;
* Tests for {@link Neo4jHealthIndicator}. * Tests for {@link Neo4jHealthIndicator}.
* *
* @author Eric Spiegelberg * @author Eric Spiegelberg
* @author Stephane Nicoll
*/ */
public class Neo4jHealthIndicatorTests { public class Neo4jHealthIndicatorTests {
private Result result;
private Session session; private Session session;
private SessionFactory sessionFactory;
private Neo4jHealthIndicator neo4jHealthIndicator; private Neo4jHealthIndicator neo4jHealthIndicator;
private Map<String, Object> emptyParameters = new HashMap<>();
@Before @Before
public void before() { public void before() {
this.result = mock(Result.class);
this.session = mock(Session.class); this.session = mock(Session.class);
this.sessionFactory = mock(SessionFactory.class); SessionFactory sessionFactory = mock(SessionFactory.class);
given(sessionFactory.openSession()).willReturn(this.session);
given(this.sessionFactory.openSession()).willReturn(this.session); this.neo4jHealthIndicator = new Neo4jHealthIndicator(sessionFactory);
this.neo4jHealthIndicator = new Neo4jHealthIndicator(this.sessionFactory);
} }
@Test @Test
public void neo4jUp() { public void neo4jUp() {
given(this.session.query(Neo4jHealthIndicator.CYPHER, this.emptyParameters)) Result result = mock(Result.class);
.willReturn(this.result); given(this.session.query(Neo4jHealthIndicator.CYPHER, Collections.EMPTY_MAP))
.willReturn(result);
int nodeCount = 500; int nodeCount = 500;
Map<String, Object> expectedCypherDetails = new HashMap<>(); Map<String, Object> expectedCypherDetails = new HashMap<>();
expectedCypherDetails.put("nodes", nodeCount); expectedCypherDetails.put("nodes", nodeCount);
List<Map<String, Object>> queryResults = new ArrayList<>(); List<Map<String, Object>> queryResults = new ArrayList<>();
queryResults.add(expectedCypherDetails); queryResults.add(expectedCypherDetails);
given(result.queryResults()).willReturn(queryResults);
given(this.result.queryResults()).willReturn(queryResults);
Health health = this.neo4jHealthIndicator.health(); Health health = this.neo4jHealthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health.getStatus()).isEqualTo(Status.UP);
Map<String, Object> details = health.getDetails(); Map<String, Object> details = health.getDetails();
int nodeCountFromDetails = (int) details.get("nodes"); int nodeCountFromDetails = (int) details.get("nodes");
Assert.assertEquals(nodeCount, nodeCountFromDetails); Assert.assertEquals(nodeCount, nodeCountFromDetails);
} }
@Test @Test
public void neo4jDown() { public void neo4jDown() {
CypherException cypherException = new CypherException("Error executing Cypher", CypherException cypherException = new CypherException("Error executing Cypher",
"Neo.ClientError.Statement.SyntaxError", "Neo.ClientError.Statement.SyntaxError",
"Unable to execute invalid Cypher"); "Unable to execute invalid Cypher");
given(this.session.query(Neo4jHealthIndicator.CYPHER, Collections.EMPTY_MAP))
given(this.session.query(Neo4jHealthIndicator.CYPHER, this.emptyParameters))
.willThrow(cypherException); .willThrow(cypherException);
Health health = this.neo4jHealthIndicator.health(); Health health = this.neo4jHealthIndicator.health();
......
...@@ -1214,6 +1214,7 @@ content into your application; rather pick only the properties that you need. ...@@ -1214,6 +1214,7 @@ content into your application; rather pick only the properties that you need.
management.health.ldap.enabled=true # Enable LDAP health check. management.health.ldap.enabled=true # Enable LDAP health check.
management.health.mail.enabled=true # Enable Mail health check. management.health.mail.enabled=true # Enable Mail health check.
management.health.mongo.enabled=true # Enable MongoDB health check. management.health.mongo.enabled=true # Enable MongoDB health check.
management.health.neo4j.enabled=true # Enable Neo4j health check.
management.health.rabbit.enabled=true # Enable RabbitMQ health check. management.health.rabbit.enabled=true # Enable RabbitMQ health check.
management.health.redis.enabled=true # Enable Redis health check. management.health.redis.enabled=true # Enable Redis health check.
management.health.solr.enabled=true # Enable Solr health check. management.health.solr.enabled=true # Enable Solr health check.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment