mirror of https://github.com/apache/lucene.git
PingRequestHandler is now directly configured with a "healthcheckFile" instead of looking for the legacy <admin><healthcheck/></admin> syntax. Filenames specified as relative paths have been fixed so that they are resolved against the data dir instead of the CWD of the java process.
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1333598 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b0a4eaba31
commit
d5eeb396a5
|
@ -78,6 +78,12 @@ Upgrading from Solr 3.6-dev
|
||||||
CommonsHttpSolrServer is now HttpSolrServer, and
|
CommonsHttpSolrServer is now HttpSolrServer, and
|
||||||
StreamingUpdateSolrServer is now ConcurrentUpdateSolrServer.
|
StreamingUpdateSolrServer is now ConcurrentUpdateSolrServer.
|
||||||
|
|
||||||
|
* The PingRequestHandler no longer looks for a <healthcheck/> option in the
|
||||||
|
(legacy) <admin> section of solrconfig.xml. Users who wish to take
|
||||||
|
advantage of this feature should configure a "healthcheckFile" init param
|
||||||
|
directly on the PingRequestHandler. As part of this change, relative file
|
||||||
|
paths have been fixed to be resolved against the data dir. See the example
|
||||||
|
solrconfig.xml and SOLR-1258 for more details.
|
||||||
|
|
||||||
Detailed Change List
|
Detailed Change List
|
||||||
----------------------
|
----------------------
|
||||||
|
@ -535,6 +541,12 @@ Other Changes
|
||||||
* SOLR-3403: Deprecated Analysis Factories now log their own deprecation messages.
|
* SOLR-3403: Deprecated Analysis Factories now log their own deprecation messages.
|
||||||
No logging support is provided by Factory parent classes. (Chris Male)
|
No logging support is provided by Factory parent classes. (Chris Male)
|
||||||
|
|
||||||
|
* SOLR-1258: PingRequestHandler is now directly configured with a
|
||||||
|
"healthcheckFile" instead of looking for the legacy
|
||||||
|
<admin><healthcheck/></admin> syntax. Filenames specified as relative
|
||||||
|
paths have been fixed so that they are resolved against the data dir
|
||||||
|
instead of the CWD of the java process. (hossman)
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
|
|
@ -464,10 +464,6 @@
|
||||||
<!-- config for the admin interface -->
|
<!-- config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>solr</defaultQuery>
|
<defaultQuery>solr</defaultQuery>
|
||||||
|
|
||||||
<!-- configure a healthcheck file for servers behind a loadbalancer
|
|
||||||
<healthcheck type="file">server-enabled</healthcheck>
|
|
||||||
-->
|
|
||||||
</admin>
|
</admin>
|
||||||
|
|
||||||
</config>
|
</config>
|
||||||
|
|
|
@ -305,10 +305,6 @@
|
||||||
<!-- config for the admin interface -->
|
<!-- config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>*:*</defaultQuery>
|
<defaultQuery>*:*</defaultQuery>
|
||||||
|
|
||||||
<!-- configure a healthcheck file for servers behind a loadbalancer
|
|
||||||
<healthcheck type="file">server-enabled</healthcheck>
|
|
||||||
-->
|
|
||||||
</admin>
|
</admin>
|
||||||
|
|
||||||
</config>
|
</config>
|
||||||
|
|
|
@ -309,10 +309,6 @@
|
||||||
<!-- config for the admin interface -->
|
<!-- config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>*:*</defaultQuery>
|
<defaultQuery>*:*</defaultQuery>
|
||||||
|
|
||||||
<!-- configure a healthcheck file for servers behind a loadbalancer
|
|
||||||
<healthcheck type="file">server-enabled</healthcheck>
|
|
||||||
-->
|
|
||||||
</admin>
|
</admin>
|
||||||
|
|
||||||
<updateRequestProcessorChain key="contentstream" default="true">
|
<updateRequestProcessorChain key="contentstream" default="true">
|
||||||
|
|
|
@ -307,10 +307,6 @@
|
||||||
<!-- config for the admin interface -->
|
<!-- config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>*:*</defaultQuery>
|
<defaultQuery>*:*</defaultQuery>
|
||||||
|
|
||||||
<!-- configure a healthcheck file for servers behind a loadbalancer
|
|
||||||
<healthcheck type="file">server-enabled</healthcheck>
|
|
||||||
-->
|
|
||||||
</admin>
|
</admin>
|
||||||
|
|
||||||
</config>
|
</config>
|
||||||
|
|
|
@ -305,10 +305,6 @@
|
||||||
<!-- config for the admin interface -->
|
<!-- config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>*:*</defaultQuery>
|
<defaultQuery>*:*</defaultQuery>
|
||||||
|
|
||||||
<!-- configure a healthcheck file for servers behind a loadbalancer
|
|
||||||
<healthcheck type="file">server-enabled</healthcheck>
|
|
||||||
-->
|
|
||||||
</admin>
|
</admin>
|
||||||
|
|
||||||
<updateRequestProcessorChain key="dataimport" default="true">
|
<updateRequestProcessorChain key="dataimport" default="true">
|
||||||
|
|
|
@ -968,11 +968,6 @@
|
||||||
<!-- config for the admin interface -->
|
<!-- config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>*</defaultQuery>
|
<defaultQuery>*</defaultQuery>
|
||||||
|
|
||||||
<!--
|
|
||||||
configure a healthcheck file for servers behind a loadbalancer
|
|
||||||
<healthcheck type="file">server-enabled</healthcheck>
|
|
||||||
-->
|
|
||||||
</admin>
|
</admin>
|
||||||
|
|
||||||
</config>
|
</config>
|
||||||
|
|
|
@ -850,11 +850,6 @@
|
||||||
<!-- config for the admin interface -->
|
<!-- config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>*</defaultQuery>
|
<defaultQuery>*</defaultQuery>
|
||||||
|
|
||||||
<!--
|
|
||||||
configure a healthcheck file for servers behind a loadbalancer
|
|
||||||
<healthcheck type="file">server-enabled</healthcheck>
|
|
||||||
-->
|
|
||||||
</admin>
|
</admin>
|
||||||
|
|
||||||
</config>
|
</config>
|
||||||
|
|
|
@ -19,31 +19,155 @@ package org.apache.solr.handler;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.text.SimpleDateFormat;
|
import java.io.IOException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.solr.common.SolrException;
|
import org.apache.solr.common.SolrException;
|
||||||
import org.apache.solr.common.params.CommonParams;
|
import org.apache.solr.common.params.CommonParams;
|
||||||
import org.apache.solr.common.params.SolrParams;
|
import org.apache.solr.common.params.SolrParams;
|
||||||
|
import org.apache.solr.common.util.NamedList;
|
||||||
import org.apache.solr.core.SolrCore;
|
import org.apache.solr.core.SolrCore;
|
||||||
|
import org.apache.solr.util.plugin.SolrCoreAware;
|
||||||
import org.apache.solr.request.SolrQueryRequest;
|
import org.apache.solr.request.SolrQueryRequest;
|
||||||
import org.apache.solr.request.SolrRequestHandler;
|
import org.apache.solr.request.SolrRequestHandler;
|
||||||
import org.apache.solr.response.SolrQueryResponse;
|
import org.apache.solr.response.SolrQueryResponse;
|
||||||
|
import org.apache.solr.schema.DateField;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ping solr core
|
* Ping Request Handler for reporting SolrCore health to a Load Balancer.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This handler is designed to be used as the endpoint for an HTTP
|
||||||
|
* Load-Balancer to use when checking the "health" or "up status" of a
|
||||||
|
* Solr server.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
|
* <p>
|
||||||
|
* In it's simplest form, the PingRequestHandler should be
|
||||||
|
* configured with some defaults indicating a request that should be
|
||||||
|
* executed. If the request succeeds, then the PingRequestHandler
|
||||||
|
* will respond back with a simple "OK" status. If the request fails,
|
||||||
|
* then the PingRequestHandler will respond back with the
|
||||||
|
* corrisponding HTTP Error code. Clients (such as load balancers)
|
||||||
|
* can be configured to poll the PingRequestHandler monitoring for
|
||||||
|
* these types of responses (or for a simple connection failure) to
|
||||||
|
* know if there is a problem with the Solr server.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <pre class="prettyprint">
|
||||||
|
* <requestHandler name="/admin/ping" class="solr.PingRequestHandler">
|
||||||
|
* <lst name="invariants">
|
||||||
|
* <str name="qt">/search</str><!-- handler to delegate to -->
|
||||||
|
* <str name="q">some test query</str>
|
||||||
|
* </lst>
|
||||||
|
* </requestHandler>
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* A more advanced option available, is to configure the handler with a
|
||||||
|
* "healthcheckFile" which can be used to enable/disable the PingRequestHandler.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <pre class="prettyprint">
|
||||||
|
* <requestHandler name="/admin/ping" class="solr.PingRequestHandler">
|
||||||
|
* <!-- relative paths are resolved against the data dir -->
|
||||||
|
* <str name="healthcheckFile">server-enabled.txt</str>
|
||||||
|
* <lst name="invariants">
|
||||||
|
* <str name="qt">/search</str><!-- handler to delegate to -->
|
||||||
|
* <str name="q">some test query</str>
|
||||||
|
* </lst>
|
||||||
|
* </requestHandler>
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>If the health check file exists, the handler will execute the
|
||||||
|
* delegated query and return status as described above.
|
||||||
|
* </li>
|
||||||
|
* <li>If the health check file does not exist, the handler will return
|
||||||
|
* an HTTP error even if the server is working fine and the delegated
|
||||||
|
* query would have succeeded
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This health check file feature can be used as a way to indicate
|
||||||
|
* to some Load Balancers that the server should be "removed from
|
||||||
|
* rotation" for maintenance, or upgrades, or whatever reason you may
|
||||||
|
* wish.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The health check file may be created/deleted by any external
|
||||||
|
* system, or the PingRequestHandler itself can be used to
|
||||||
|
* create/delete the file by specifying an "action" param in a
|
||||||
|
* request:
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li><code>http://.../ping?action=enable</code>
|
||||||
|
* - creates the health check file if it does not already exist
|
||||||
|
* </li>
|
||||||
|
* <li><code>http://.../ping?action=disable</code>
|
||||||
|
* - deletes the health check file if it exists
|
||||||
|
* </li>
|
||||||
|
* <li><code>http://.../ping?action=status</code>
|
||||||
|
* - returns a status code indicating if the healthcheck file exists
|
||||||
|
* ("<code>enabled</code>") or not ("<code>disabled<code>")
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
* @since solr 1.3
|
* @since solr 1.3
|
||||||
*/
|
*/
|
||||||
public class PingRequestHandler extends RequestHandlerBase
|
public class PingRequestHandler extends RequestHandlerBase implements SolrCoreAware
|
||||||
{
|
{
|
||||||
|
public static Logger log = LoggerFactory.getLogger(PingRequestHandler.class);
|
||||||
|
|
||||||
SimpleDateFormat formatRFC3339 = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ss.SZ");
|
public static final String HEALTHCHECK_FILE_PARAM = "healthcheckFile";
|
||||||
protected enum ACTIONS {STATUS, ENABLE, DISABLE, PING};
|
protected enum ACTIONS {STATUS, ENABLE, DISABLE, PING};
|
||||||
private String healthcheck = null;
|
|
||||||
|
|
||||||
|
private String healthFileName = null;
|
||||||
|
private File healthcheck = null;
|
||||||
|
|
||||||
|
public void init(NamedList args) {
|
||||||
|
super.init(args);
|
||||||
|
Object tmp = args.get(HEALTHCHECK_FILE_PARAM);
|
||||||
|
healthFileName = (null == tmp ? null : tmp.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void inform( SolrCore core ) {
|
||||||
|
if (null != healthFileName) {
|
||||||
|
healthcheck = new File(healthFileName);
|
||||||
|
if ( ! healthcheck.isAbsolute()) {
|
||||||
|
healthcheck = new File(core.getDataDir(), healthFileName);
|
||||||
|
healthcheck = healthcheck.getAbsoluteFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! healthcheck.getParentFile().canWrite()) {
|
||||||
|
// this is not fatal, users may not care about enable/disable via
|
||||||
|
// solr request, file might be touched/deleted by an external system
|
||||||
|
log.warn("Directory for configured healthcheck file is not writable by solr, PingRequestHandler will not be able to control enable/disable: {}",
|
||||||
|
healthcheck.getParentFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the healthcheck flag-file is enabled but does not exist,
|
||||||
|
* otherwise (no file configured, or file configured and exists)
|
||||||
|
* returns false.
|
||||||
|
*/
|
||||||
|
public boolean isPingDisabled() {
|
||||||
|
return (null != healthcheck && ! healthcheck.exists() );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception
|
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception
|
||||||
{
|
{
|
||||||
|
@ -51,9 +175,6 @@ public class PingRequestHandler extends RequestHandlerBase
|
||||||
SolrParams params = req.getParams();
|
SolrParams params = req.getParams();
|
||||||
SolrCore core = req.getCore();
|
SolrCore core = req.getCore();
|
||||||
|
|
||||||
// Check if the service is available
|
|
||||||
healthcheck = core.getSolrConfig().get("admin/healthcheck/text()", null );
|
|
||||||
|
|
||||||
String actionParam = params.get("action");
|
String actionParam = params.get("action");
|
||||||
ACTIONS action = null;
|
ACTIONS action = null;
|
||||||
if (actionParam == null){
|
if (actionParam == null){
|
||||||
|
@ -70,32 +191,28 @@ public class PingRequestHandler extends RequestHandlerBase
|
||||||
}
|
}
|
||||||
switch(action){
|
switch(action){
|
||||||
case PING:
|
case PING:
|
||||||
if( healthcheck != null && !new File(healthcheck).exists() ) {
|
if( isPingDisabled() ) {
|
||||||
throw new SolrException(SolrException.ErrorCode.SERVICE_UNAVAILABLE, "Service disabled");
|
throw new SolrException(SolrException.ErrorCode.SERVICE_UNAVAILABLE,
|
||||||
|
"Service disabled");
|
||||||
}
|
}
|
||||||
handlePing(req, rsp);
|
handlePing(req, rsp);
|
||||||
break;
|
break;
|
||||||
case ENABLE:
|
case ENABLE:
|
||||||
handleEnable(healthcheck,true);
|
handleEnable(true);
|
||||||
break;
|
break;
|
||||||
case DISABLE:
|
case DISABLE:
|
||||||
handleEnable(healthcheck,false);
|
handleEnable(false);
|
||||||
break;
|
break;
|
||||||
case STATUS:
|
case STATUS:
|
||||||
if( healthcheck == null){
|
if( healthcheck == null ){
|
||||||
SolrException e = new SolrException(SolrException.ErrorCode.SERVICE_UNAVAILABLE, "healthcheck not configured");
|
SolrException e = new SolrException
|
||||||
|
(SolrException.ErrorCode.SERVICE_UNAVAILABLE,
|
||||||
|
"healthcheck not configured");
|
||||||
rsp.setException(e);
|
rsp.setException(e);
|
||||||
}
|
} else {
|
||||||
else {
|
rsp.add( "status", isPingDisabled() ? "disabled" : "enabled" );
|
||||||
if ( new File(healthcheck).exists() ){
|
|
||||||
rsp.add( "status", "enabled");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rsp.add( "status", "disabled");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handlePing(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception
|
protected void handlePing(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception
|
||||||
|
@ -136,24 +253,25 @@ public class PingRequestHandler extends RequestHandlerBase
|
||||||
rsp.add( "status", "OK" );
|
rsp.add( "status", "OK" );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleEnable(String healthcheck, boolean enable) throws Exception
|
protected void handleEnable(boolean enable) throws SolrException {
|
||||||
{
|
|
||||||
if (healthcheck == null) {
|
if (healthcheck == null) {
|
||||||
throw new SolrException(SolrException.ErrorCode.SERVICE_UNAVAILABLE,
|
throw new SolrException(SolrException.ErrorCode.SERVICE_UNAVAILABLE,
|
||||||
"No healthcheck file defined.");
|
"No healthcheck file defined.");
|
||||||
}
|
}
|
||||||
File enableFile = new File(healthcheck);
|
|
||||||
if ( enable ) {
|
if ( enable ) {
|
||||||
enableFile.createNewFile();
|
try {
|
||||||
|
// write out when the file was created
|
||||||
// write out when the file was created
|
FileUtils.write(healthcheck,
|
||||||
FileWriter fw = new FileWriter(enableFile);
|
DateField.formatExternal(new Date()), "UTF-8");
|
||||||
fw.write(formatRFC3339.format(new Date()));
|
} catch (IOException e) {
|
||||||
fw.close();
|
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
|
||||||
|
"Unable to write healthcheck flag file", e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (enableFile.exists() && !enableFile.delete()){
|
if (healthcheck.exists() && !healthcheck.delete()){
|
||||||
throw new SolrException( SolrException.ErrorCode.NOT_FOUND,"Did not successfully delete healthcheck file:'"+healthcheck+"'");
|
throw new SolrException(SolrException.ErrorCode.NOT_FOUND,
|
||||||
|
"Did not successfully delete healthcheck file: "
|
||||||
|
+healthcheck.getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,21 +20,24 @@ package org.apache.solr.handler;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.solr.SolrTestCaseJ4;
|
import org.apache.solr.SolrTestCaseJ4;
|
||||||
import org.apache.solr.common.SolrException;
|
import org.apache.solr.common.SolrException;
|
||||||
|
import org.apache.solr.common.util.NamedList;
|
||||||
import org.apache.solr.request.SolrQueryRequest;
|
import org.apache.solr.request.SolrQueryRequest;
|
||||||
import org.apache.solr.response.SolrQueryResponse;
|
import org.apache.solr.response.SolrQueryResponse;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
|
|
||||||
public class PingRequestHandlerTest extends SolrTestCaseJ4 {
|
public class PingRequestHandlerTest extends SolrTestCaseJ4 {
|
||||||
|
|
||||||
private String healthcheck = "server-enabled";
|
private final String fileName = this.getClass().getName() + ".server-enabled";
|
||||||
private File healthcheckFile = new File(healthcheck);
|
private File healthcheckFile = null;
|
||||||
private PingRequestHandler handler = null;
|
private PingRequestHandler handler = null;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
|
@ -43,116 +46,149 @@ public class PingRequestHandlerTest extends SolrTestCaseJ4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() {
|
public void before() throws IOException {
|
||||||
healthcheckFile.delete();
|
|
||||||
handler = new PingRequestHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPing() throws Exception {
|
|
||||||
|
|
||||||
SolrQueryRequest req = req();
|
|
||||||
SolrQueryResponse rsp = new SolrQueryResponse();
|
|
||||||
|
|
||||||
handler.handleRequestBody(req, rsp);
|
|
||||||
String status = (String) rsp.getValues().get("status");
|
|
||||||
assertEquals("OK", status);
|
|
||||||
req.close();
|
|
||||||
|
|
||||||
req = req("action","ping");
|
|
||||||
rsp = new SolrQueryResponse();
|
|
||||||
|
|
||||||
handler.handleRequestBody(req, rsp);
|
|
||||||
status = (String) rsp.getValues().get("status");
|
|
||||||
assertEquals("OK", status);
|
|
||||||
req.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEnablingServer() throws Exception {
|
|
||||||
|
|
||||||
|
|
||||||
handler.handleEnable(healthcheck, true);
|
|
||||||
|
|
||||||
assertTrue(healthcheckFile.exists());
|
|
||||||
|
|
||||||
SolrQueryRequest req = req();
|
|
||||||
SolrQueryResponse rsp = new SolrQueryResponse();
|
|
||||||
|
|
||||||
handler.handlePing(req, rsp);
|
// by default, use relative file in dataDir
|
||||||
String status = (String) rsp.getValues().get("status");
|
healthcheckFile = new File(dataDir, fileName);
|
||||||
assertEquals("OK", status);
|
String fileNameParam = fileName;
|
||||||
req.close();
|
|
||||||
|
// sometimes randomly use an absolute File path instead
|
||||||
FileReader fr = new FileReader(healthcheckFile);
|
if (random().nextBoolean()) {
|
||||||
|
healthcheckFile = new File(TEMP_DIR, fileName);
|
||||||
BufferedReader br = new BufferedReader(fr);
|
fileNameParam = healthcheckFile.getAbsolutePath();
|
||||||
String s = br.readLine();
|
}
|
||||||
assertNotNull(s);
|
|
||||||
|
if (healthcheckFile.exists()) FileUtils.forceDelete(healthcheckFile);
|
||||||
|
|
||||||
|
handler = new PingRequestHandler();
|
||||||
|
NamedList initParams = new NamedList();
|
||||||
|
initParams.add(PingRequestHandler.HEALTHCHECK_FILE_PARAM,
|
||||||
|
fileNameParam);
|
||||||
|
handler.init(initParams);
|
||||||
|
handler.inform(h.getCore());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
public void testPingWithNoHealthCheck() throws Exception {
|
||||||
public void testDisablingServer() throws Exception {
|
|
||||||
|
|
||||||
|
// for this test, we don't want any healthcheck file configured at all
|
||||||
|
handler = new PingRequestHandler();
|
||||||
|
handler.init(new NamedList());
|
||||||
|
handler.inform(h.getCore());
|
||||||
|
|
||||||
|
SolrQueryResponse rsp = null;
|
||||||
|
|
||||||
|
rsp = makeRequest(handler, req());
|
||||||
|
assertEquals("OK", rsp.getValues().get("status"));
|
||||||
|
|
||||||
|
rsp = makeRequest(handler, req("action","ping"));
|
||||||
|
assertEquals("OK", rsp.getValues().get("status"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testEnablingServer() throws Exception {
|
||||||
|
|
||||||
|
assertTrue(! healthcheckFile.exists());
|
||||||
|
|
||||||
|
// first make sure that ping responds back that the service is disabled
|
||||||
|
|
||||||
|
try {
|
||||||
|
makeRequest(handler, req());
|
||||||
|
fail("Should have thrown a SolrException because not enabled yet");
|
||||||
|
} catch (SolrException se){
|
||||||
|
assertEquals(SolrException.ErrorCode.SERVICE_UNAVAILABLE.code,se.code());
|
||||||
|
}
|
||||||
|
|
||||||
|
// now enable
|
||||||
|
|
||||||
|
makeRequest(handler, req("action", "enable"));
|
||||||
|
|
||||||
|
assertTrue(healthcheckFile.exists());
|
||||||
|
assertNotNull(FileUtils.readFileToString(healthcheckFile), "UTF-8");
|
||||||
|
|
||||||
|
// now verify that the handler response with success
|
||||||
|
|
||||||
|
SolrQueryResponse rsp = makeRequest(handler, req());
|
||||||
|
assertEquals("OK", rsp.getValues().get("status"));
|
||||||
|
|
||||||
|
// enable when already enabled shouldn't cause any problems
|
||||||
|
makeRequest(handler, req("action", "enable"));
|
||||||
|
assertTrue(healthcheckFile.exists());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDisablingServer() throws Exception {
|
||||||
|
|
||||||
|
assertTrue(! healthcheckFile.exists());
|
||||||
|
|
||||||
healthcheckFile.createNewFile();
|
healthcheckFile.createNewFile();
|
||||||
|
|
||||||
|
// first make sure that ping responds back that the service is enabled
|
||||||
|
|
||||||
|
SolrQueryResponse rsp = makeRequest(handler, req());
|
||||||
|
assertEquals("OK", rsp.getValues().get("status"));
|
||||||
|
|
||||||
|
// now disable
|
||||||
|
|
||||||
handler.handleEnable(healthcheck, false);
|
makeRequest(handler, req("action", "disable"));
|
||||||
|
|
||||||
assertFalse(healthcheckFile.exists());
|
assertFalse(healthcheckFile.exists());
|
||||||
|
|
||||||
|
// now make sure that ping responds back that the service is disabled
|
||||||
|
|
||||||
|
try {
|
||||||
|
makeRequest(handler, req());
|
||||||
|
fail("Should have thrown a SolrException because not enabled yet");
|
||||||
|
} catch (SolrException se){
|
||||||
|
assertEquals(SolrException.ErrorCode.SERVICE_UNAVAILABLE.code,se.code());
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable when already disabled shouldn't cause any problems
|
||||||
|
makeRequest(handler, req("action", "disable"));
|
||||||
|
assertFalse(healthcheckFile.exists());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Ignore // because of how we load the healthcheck file, we have to change it in schema.xml
|
|
||||||
public void testGettingStatus() throws Exception {
|
public void testGettingStatus() throws Exception {
|
||||||
|
SolrQueryResponse rsp = null;
|
||||||
|
|
||||||
|
handler.handleEnable(true);
|
||||||
|
|
||||||
|
rsp = makeRequest(handler, req("action", "status"));
|
||||||
handler.handleEnable(healthcheck, true);
|
assertEquals("enabled", rsp.getValues().get("status"));
|
||||||
|
|
||||||
|
|
||||||
SolrQueryRequest req = req("action", "status");
|
|
||||||
SolrQueryResponse rsp = new SolrQueryResponse();
|
|
||||||
|
|
||||||
handler.handleRequestBody(req, rsp);
|
|
||||||
|
|
||||||
String status = (String) rsp.getValues().get("status");
|
|
||||||
assertEquals("enabled", status);
|
|
||||||
|
|
||||||
req.close();
|
|
||||||
|
|
||||||
handler.handleEnable(healthcheck, false);
|
handler.handleEnable(false);
|
||||||
|
|
||||||
req = req("action", "status");
|
rsp = makeRequest(handler, req("action", "status"));
|
||||||
rsp = new SolrQueryResponse();
|
assertEquals("disabled", rsp.getValues().get("status"));
|
||||||
|
|
||||||
handler.handleRequestBody(req, rsp);
|
|
||||||
|
|
||||||
status = (String) rsp.getValues().get("status");
|
|
||||||
assertEquals("disabled", status);
|
|
||||||
|
|
||||||
req.close();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBadActionRaisesException() throws Exception {
|
public void testBadActionRaisesException() throws Exception {
|
||||||
|
|
||||||
SolrQueryRequest req = req("action", "badaction");
|
|
||||||
SolrQueryResponse rsp = new SolrQueryResponse();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
handler.handleRequestBody(req, rsp);
|
SolrQueryResponse rsp = makeRequest(handler, req("action", "badaction"));
|
||||||
fail("Should have thrown a SolrException for the bad action");
|
fail("Should have thrown a SolrException for the bad action");
|
||||||
}
|
} catch (SolrException se){
|
||||||
catch (SolrException se){
|
|
||||||
assertEquals(SolrException.ErrorCode.BAD_REQUEST.code,se.code());
|
assertEquals(SolrException.ErrorCode.BAD_REQUEST.code,se.code());
|
||||||
}
|
}
|
||||||
|
|
||||||
req.close();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper Method: Executes the request against the handler, returns
|
||||||
|
* the response, and closes the request.
|
||||||
|
*/
|
||||||
|
private SolrQueryResponse makeRequest(PingRequestHandler handler,
|
||||||
|
SolrQueryRequest req)
|
||||||
|
throws Exception {
|
||||||
|
|
||||||
|
SolrQueryResponse rsp = new SolrQueryResponse();
|
||||||
|
try {
|
||||||
|
handler.handleRequestBody(req, rsp);
|
||||||
|
} finally {
|
||||||
|
req.close();
|
||||||
|
}
|
||||||
|
return rsp;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -488,10 +488,6 @@
|
||||||
<!-- config for the admin interface -->
|
<!-- config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>*:*</defaultQuery>
|
<defaultQuery>*:*</defaultQuery>
|
||||||
|
|
||||||
<!-- configure a healthcheck file for servers behind a loadbalancer
|
|
||||||
<healthcheck type="file">server-enabled</healthcheck>
|
|
||||||
-->
|
|
||||||
</admin>
|
</admin>
|
||||||
|
|
||||||
</config>
|
</config>
|
||||||
|
|
|
@ -674,10 +674,6 @@
|
||||||
<!-- config for the admin interface -->
|
<!-- config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>solr</defaultQuery>
|
<defaultQuery>solr</defaultQuery>
|
||||||
|
|
||||||
<!-- configure a healthcheck file for servers behind a loadbalancer
|
|
||||||
<healthcheck type="file">server-enabled</healthcheck>
|
|
||||||
-->
|
|
||||||
</admin>
|
</admin>
|
||||||
|
|
||||||
</config>
|
</config>
|
||||||
|
|
|
@ -487,10 +487,6 @@
|
||||||
<!-- config for the admin interface -->
|
<!-- config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>*:*</defaultQuery>
|
<defaultQuery>*:*</defaultQuery>
|
||||||
|
|
||||||
<!-- configure a healthcheck file for servers behind a loadbalancer
|
|
||||||
<healthcheck type="file">server-enabled</healthcheck>
|
|
||||||
-->
|
|
||||||
</admin>
|
</admin>
|
||||||
|
|
||||||
</config>
|
</config>
|
||||||
|
|
|
@ -486,10 +486,6 @@
|
||||||
<!-- config for the admin interface -->
|
<!-- config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>*:*</defaultQuery>
|
<defaultQuery>*:*</defaultQuery>
|
||||||
|
|
||||||
<!-- configure a healthcheck file for servers behind a loadbalancer
|
|
||||||
<healthcheck type="file">server-enabled</healthcheck>
|
|
||||||
-->
|
|
||||||
</admin>
|
</admin>
|
||||||
|
|
||||||
</config>
|
</config>
|
||||||
|
|
|
@ -311,10 +311,6 @@
|
||||||
<!-- config for the admin interface -->
|
<!-- config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>*:*</defaultQuery>
|
<defaultQuery>*:*</defaultQuery>
|
||||||
|
|
||||||
<!-- configure a healthcheck file for servers behind a loadbalancer
|
|
||||||
<healthcheck type="file">server-enabled</healthcheck>
|
|
||||||
-->
|
|
||||||
</admin>
|
</admin>
|
||||||
|
|
||||||
</config>
|
</config>
|
||||||
|
|
|
@ -1064,6 +1064,12 @@
|
||||||
<lst name="defaults">
|
<lst name="defaults">
|
||||||
<str name="echoParams">all</str>
|
<str name="echoParams">all</str>
|
||||||
</lst>
|
</lst>
|
||||||
|
<!-- An optional feature of the PingRequestHandler is to configure the
|
||||||
|
handler with a "healthcheckFile" which can be used to enable/disable
|
||||||
|
the PingRequestHandler.
|
||||||
|
relative paths are resolved against the data dir
|
||||||
|
-->
|
||||||
|
<!-- <str name="healthcheckFile">server-enabled.txt</str> -->
|
||||||
</requestHandler>
|
</requestHandler>
|
||||||
|
|
||||||
<!-- Echo the request contents back to the client -->
|
<!-- Echo the request contents back to the client -->
|
||||||
|
@ -1683,13 +1689,6 @@
|
||||||
<!-- Legacy config for the admin interface -->
|
<!-- Legacy config for the admin interface -->
|
||||||
<admin>
|
<admin>
|
||||||
<defaultQuery>*:*</defaultQuery>
|
<defaultQuery>*:*</defaultQuery>
|
||||||
|
|
||||||
<!-- configure a healthcheck file for servers behind a
|
|
||||||
loadbalancer
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
<healthcheck type="file">server-enabled</healthcheck>
|
|
||||||
-->
|
|
||||||
</admin>
|
</admin>
|
||||||
|
|
||||||
</config>
|
</config>
|
||||||
|
|
Loading…
Reference in New Issue