org.springframework.boot.actuate.solr.SolrHealthIndicator Maven / Gradle / Ivy
/*
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.solr;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient.RemoteSolrException;
import org.apache.solr.client.solrj.request.CoreAdminRequest;
import org.apache.solr.common.params.CoreAdminParams;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.Status;
/**
* {@link HealthIndicator} for Apache Solr.
*
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Markus Schuch
* @author Phillip Webb
* @since 2.0.0
*/
public class SolrHealthIndicator extends AbstractHealthIndicator {
private static final int HTTP_NOT_FOUND_STATUS = 404;
private final SolrClient solrClient;
private volatile StatusCheck statusCheck;
public SolrHealthIndicator(SolrClient solrClient) {
super("Solr health check failed");
this.solrClient = solrClient;
}
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
int statusCode = initializeStatusCheck();
Status status = (statusCode != 0) ? Status.DOWN : Status.UP;
builder.status(status).withDetail("status", statusCode).withDetail("detectedPathType",
this.statusCheck.getPathType());
}
private int initializeStatusCheck() throws Exception {
StatusCheck statusCheck = this.statusCheck;
if (statusCheck != null) {
// Already initilized
return statusCheck.getStatus(this.solrClient);
}
try {
return initializeStatusCheck(new RootStatusCheck());
}
catch (RemoteSolrException ex) {
// 404 is thrown when SolrClient has a baseUrl pointing to a particular core.
if (ex.code() == HTTP_NOT_FOUND_STATUS) {
return initializeStatusCheck(new ParticularCoreStatusCheck());
}
throw ex;
}
}
private int initializeStatusCheck(StatusCheck statusCheck) throws Exception {
int result = statusCheck.getStatus(this.solrClient);
this.statusCheck = statusCheck;
return result;
}
/**
* Strategy used to perform the status check.
*/
private abstract static class StatusCheck {
private final String pathType;
StatusCheck(String pathType) {
this.pathType = pathType;
}
abstract int getStatus(SolrClient client) throws Exception;
String getPathType() {
return this.pathType;
}
}
/**
* {@link StatusCheck} used when {@code baseUrl} points to the root context.
*/
private static class RootStatusCheck extends StatusCheck {
RootStatusCheck() {
super("root");
}
@Override
public int getStatus(SolrClient client) throws Exception {
CoreAdminRequest request = new CoreAdminRequest();
request.setAction(CoreAdminParams.CoreAdminAction.STATUS);
return request.process(client).getStatus();
}
}
/**
* {@link StatusCheck} used when {@code baseUrl} points to the particular core.
*/
private static class ParticularCoreStatusCheck extends StatusCheck {
ParticularCoreStatusCheck() {
super("particular core");
}
@Override
public int getStatus(SolrClient client) throws Exception {
return client.ping().getStatus();
}
}
}