Fallback to ping if Solr URL references core

Update `SolrHealthIndicator` to fallback to a basic ping operation if
the `baseUrl` references a particular core rather than the root context.

Prior to this commit, if the Solr `baseUrl` pointed to a particular
core then the health indicator would incorrectly report `DOWN`.

See gh-16477
This commit is contained in:
Markus Schuch
2019-04-06 16:53:49 +02:00
committed by Phillip Webb
parent ca6395c388
commit b9764e8de8
2 changed files with 135 additions and 6 deletions

View File

@@ -19,7 +19,9 @@ package org.springframework.boot.actuate.solr;
import java.io.IOException;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.request.CoreAdminRequest;
import org.apache.solr.client.solrj.response.SolrPingResponse;
import org.apache.solr.common.util.NamedList;
import org.junit.After;
import org.junit.Test;
@@ -33,6 +35,9 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* Tests for {@link SolrHealthIndicator}
@@ -51,23 +56,79 @@ public class SolrHealthIndicatorTests {
}
@Test
public void solrIsUp() throws Exception {
public void solrIsUpWithBaseUrlPointsToRoot() throws Exception {
SolrClient solrClient = mock(SolrClient.class);
given(solrClient.request(any(CoreAdminRequest.class), isNull())).willReturn(mockResponse(0));
SolrHealthIndicator healthIndicator = new SolrHealthIndicator(solrClient);
Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails().get("status")).isEqualTo(0);
assertThat(health.getDetails().get("detectedPathType")).isEqualTo(SolrHealthIndicator.PathType.ROOT.toString());
verify(solrClient, times(1)).request(any(CoreAdminRequest.class), isNull());
verifyNoMoreInteractions(solrClient);
}
@Test
public void solrIsUpAndRequestFailed() throws Exception {
public void solrIsUpWithBaseUrlPointsToParticularCore() throws Exception {
SolrClient solrClient = mock(SolrClient.class);
given(solrClient.request(any(CoreAdminRequest.class), isNull()))
.willThrow(new HttpSolrClient.RemoteSolrException("mock", 404, "", null));
given(solrClient.ping()).willReturn(mockPingResponse(0));
SolrHealthIndicator healthIndicator = new SolrHealthIndicator(solrClient);
Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails().get("status")).isEqualTo(0);
assertThat(health.getDetails().get("detectedPathType"))
.isEqualTo(SolrHealthIndicator.PathType.PARTICULAR_CORE.toString());
verify(solrClient, times(1)).request(any(CoreAdminRequest.class), isNull());
verify(solrClient, times(1)).ping();
verifyNoMoreInteractions(solrClient);
}
@Test
public void pathTypeIsRememberedForConsecutiveChecks() throws Exception {
SolrClient solrClient = mock(SolrClient.class);
given(solrClient.request(any(CoreAdminRequest.class), isNull()))
.willThrow(new HttpSolrClient.RemoteSolrException("mock", 404, "", null));
given(solrClient.ping()).willReturn(mockPingResponse(0));
SolrHealthIndicator healthIndicator = new SolrHealthIndicator(solrClient);
healthIndicator.health();
verify(solrClient, times(1)).request(any(CoreAdminRequest.class), isNull());
verify(solrClient, times(1)).ping();
verifyNoMoreInteractions(solrClient);
healthIndicator.health();
verify(solrClient, times(2)).ping();
verifyNoMoreInteractions(solrClient);
}
@Test
public void solrIsUpAndRequestFailedWithBaseUrlPointsToRoot() throws Exception {
SolrClient solrClient = mock(SolrClient.class);
given(solrClient.request(any(CoreAdminRequest.class), isNull())).willReturn(mockResponse(400));
SolrHealthIndicator healthIndicator = new SolrHealthIndicator(solrClient);
Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
assertThat(health.getDetails().get("status")).isEqualTo(400);
assertThat(health.getDetails().get("detectedPathType")).isEqualTo(SolrHealthIndicator.PathType.ROOT.toString());
verify(solrClient, times(1)).request(any(CoreAdminRequest.class), isNull());
verifyNoMoreInteractions(solrClient);
}
@Test
public void solrIsUpAndRequestFailedWithBaseUrlPointsToParticularCore() throws Exception {
SolrClient solrClient = mock(SolrClient.class);
given(solrClient.request(any(CoreAdminRequest.class), isNull()))
.willThrow(new HttpSolrClient.RemoteSolrException("mock", 404, "", null));
given(solrClient.ping()).willReturn(mockPingResponse(400));
SolrHealthIndicator healthIndicator = new SolrHealthIndicator(solrClient);
Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
assertThat(health.getDetails().get("status")).isEqualTo(400);
assertThat(health.getDetails().get("detectedPathType"))
.isEqualTo(SolrHealthIndicator.PathType.PARTICULAR_CORE.toString());
verify(solrClient, times(1)).request(any(CoreAdminRequest.class), isNull());
verify(solrClient, times(1)).ping();
verifyNoMoreInteractions(solrClient);
}
@Test
@@ -79,6 +140,8 @@ public class SolrHealthIndicatorTests {
Health health = healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
assertThat((String) health.getDetails().get("error")).contains("Connection failed");
verify(solrClient, times(1)).request(any(CoreAdminRequest.class), isNull());
verifyNoMoreInteractions(solrClient);
}
private NamedList<Object> mockResponse(int status) {
@@ -89,4 +152,10 @@ public class SolrHealthIndicatorTests {
return response;
}
private SolrPingResponse mockPingResponse(int status) {
SolrPingResponse pingResponse = new SolrPingResponse();
pingResponse.setResponse(mockResponse(status));
return pingResponse;
}
}