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
pull/8929/head
Stephane Nicoll 8 years ago
parent 3c28687279
commit 9d88e477f3

@ -1,5 +1,5 @@
/* /*
* 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 @@
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 {
@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);
}
} }
} }

@ -1,5 +1,5 @@
/* /*
* 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;
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
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 {
@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 {
.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;
}
} }

Loading…
Cancel
Save