Commit 9d88e477 authored by Stephane Nicoll's avatar Stephane Nicoll

Fix Solr health indicator

This commit changes the solr health indicator to request the status of
all available cores, rather than invoking a generic ping on the admin
handler.

Recent versions of Solr now have a ping handler per core and the general
admin handler is gone, leading to incorrect health status. For backward
compatible reason the `solrStatus` attribute is kept to `OK` if all cores
are running properly (that's actually `0` behind the scenes).

Closes gh-8463
parent 3c286872
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -17,11 +17,15 @@ ...@@ -17,11 +17,15 @@
package org.springframework.boot.actuate.health; package org.springframework.boot.actuate.health;
import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.request.CoreAdminRequest;
import org.apache.solr.client.solrj.response.CoreAdminResponse;
import org.apache.solr.common.params.CoreAdminParams;
/** /**
* {@link HealthIndicator} for Apache Solr. * {@link HealthIndicator} for Apache Solr.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Stephane Nicoll
* @since 1.1.0 * @since 1.1.0
*/ */
public class SolrHealthIndicator extends AbstractHealthIndicator { public class SolrHealthIndicator extends AbstractHealthIndicator {
...@@ -34,8 +38,16 @@ public class SolrHealthIndicator extends AbstractHealthIndicator { ...@@ -34,8 +38,16 @@ public class SolrHealthIndicator extends AbstractHealthIndicator {
@Override @Override
protected void doHealthCheck(Health.Builder builder) throws Exception { protected void doHealthCheck(Health.Builder builder) throws Exception {
Object status = this.solrClient.ping().getResponse().get("status"); CoreAdminRequest request = new CoreAdminRequest();
builder.up().withDetail("solrStatus", status); request.setAction(CoreAdminParams.CoreAdminAction.STATUS);
CoreAdminResponse response = request.process(this.solrClient);
int status = response.getStatus();
if (status == 0) {
builder.up().withDetail("solrStatus", "OK");
}
else {
builder.down().withDetail("solrStatus", status);
}
} }
} }
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -19,7 +19,7 @@ package org.springframework.boot.actuate.health; ...@@ -19,7 +19,7 @@ package org.springframework.boot.actuate.health;
import java.io.IOException; import java.io.IOException;
import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.response.SolrPingResponse; import org.apache.solr.client.solrj.request.CoreAdminRequest;
import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.NamedList;
import org.junit.After; import org.junit.After;
import org.junit.Test; import org.junit.Test;
...@@ -32,6 +32,8 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext ...@@ -32,6 +32,8 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
/** /**
...@@ -65,21 +67,30 @@ public class SolrHealthIndicatorTests { ...@@ -65,21 +67,30 @@ public class SolrHealthIndicatorTests {
@Test @Test
public void solrIsUp() throws Exception { public void solrIsUp() throws Exception {
SolrClient solrClient = mock(SolrClient.class); SolrClient solrClient = mock(SolrClient.class);
SolrPingResponse pingResponse = new SolrPingResponse(); given(solrClient.request(any(CoreAdminRequest.class), (String) isNull()))
NamedList<Object> response = new NamedList<Object>(); .willReturn(mockResponse(0));
response.add("status", "OK");
pingResponse.setResponse(response);
given(solrClient.ping()).willReturn(pingResponse);
SolrHealthIndicator healthIndicator = new SolrHealthIndicator(solrClient); SolrHealthIndicator healthIndicator = new SolrHealthIndicator(solrClient);
Health health = healthIndicator.health(); Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails().get("solrStatus")).isEqualTo("OK"); assertThat(health.getDetails().get("solrStatus")).isEqualTo("OK");
} }
@Test
public void solrIsUpAndRequestFailed() throws Exception {
SolrClient solrClient = mock(SolrClient.class);
given(solrClient.request(any(CoreAdminRequest.class), (String) isNull()))
.willReturn(mockResponse(400));
SolrHealthIndicator healthIndicator = new SolrHealthIndicator(solrClient);
Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
assertThat(health.getDetails().get("solrStatus")).isEqualTo(400);
}
@Test @Test
public void solrIsDown() throws Exception { public void solrIsDown() throws Exception {
SolrClient solrClient = mock(SolrClient.class); SolrClient solrClient = mock(SolrClient.class);
given(solrClient.ping()).willThrow(new IOException("Connection failed")); given(solrClient.request(any(CoreAdminRequest.class), (String) isNull()))
.willThrow(new IOException("Connection failed"));
SolrHealthIndicator healthIndicator = new SolrHealthIndicator(solrClient); SolrHealthIndicator healthIndicator = new SolrHealthIndicator(solrClient);
Health health = healthIndicator.health(); Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN); assertThat(health.getStatus()).isEqualTo(Status.DOWN);
...@@ -87,4 +98,12 @@ public class SolrHealthIndicatorTests { ...@@ -87,4 +98,12 @@ public class SolrHealthIndicatorTests {
.contains("Connection failed")); .contains("Connection failed"));
} }
private NamedList<Object> mockResponse(int status) {
NamedList<Object> response = new NamedList<Object>();
NamedList<Object> headers = new NamedList<Object>();
headers.add("status", status);
response.add("responseHeader", headers);
return response;
}
} }
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