SOLR-3301: Add PingRequestHandler for Trunk

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1329263 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Stefan Matheis 2012-04-23 14:37:39 +00:00
parent a047f3f9dd
commit a316fb69ee
4 changed files with 251 additions and 16 deletions

View File

@ -18,6 +18,9 @@
package org.apache.solr.handler; package org.apache.solr.handler;
import java.io.File; import java.io.File;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
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;
@ -35,17 +38,70 @@ import org.apache.solr.response.SolrQueryResponse;
*/ */
public class PingRequestHandler extends RequestHandlerBase public class PingRequestHandler extends RequestHandlerBase
{ {
SimpleDateFormat formatRFC3339 = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ss.SZ");
protected enum ACTIONS {STATUS, ENABLE, DISABLE, PING};
private String healthcheck = null;
@Override @Override
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception
{ {
SolrParams params = req.getParams(); SolrParams params = req.getParams();
SolrCore core = req.getCore(); SolrCore core = req.getCore();
// Check if the service is available // Check if the service is available
String healthcheck = core.getSolrConfig().get("admin/healthcheck/text()", null ); healthcheck = core.getSolrConfig().get("admin/healthcheck/text()", null );
if( healthcheck != null && !new File(healthcheck).exists() ) {
throw new SolrException(SolrException.ErrorCode.SERVICE_UNAVAILABLE, "Service disabled"); String actionParam = params.get("action");
ACTIONS action = null;
if (actionParam == null){
action = ACTIONS.PING;
} }
else {
try {
action = ACTIONS.valueOf(actionParam.toUpperCase());
}
catch (IllegalArgumentException iae){
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
"Unknown action: " + actionParam);
}
}
switch(action){
case PING:
if( healthcheck != null && !new File(healthcheck).exists() ) {
throw new SolrException(SolrException.ErrorCode.SERVICE_UNAVAILABLE, "Service disabled");
}
handlePing(req, rsp);
break;
case ENABLE:
handleEnable(healthcheck,true);
break;
case DISABLE:
handleEnable(healthcheck,false);
break;
case STATUS:
if( healthcheck == null){
SolrException e = new SolrException(SolrException.ErrorCode.SERVICE_UNAVAILABLE, "healthcheck not configured");
rsp.setException(e);
}
else {
if ( new File(healthcheck).exists() ){
rsp.add( "status", "enabled");
}
else {
rsp.add( "status", "disabled");
}
}
}
}
protected void handlePing(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception
{
SolrParams params = req.getParams();
SolrCore core = req.getCore();
// Get the RequestHandler // Get the RequestHandler
String qt = params.get( CommonParams.QT );//optional; you get the default otherwise String qt = params.get( CommonParams.QT );//optional; you get the default otherwise
@ -79,7 +135,27 @@ public class PingRequestHandler extends RequestHandlerBase
rsp.add( "status", "OK" ); rsp.add( "status", "OK" );
} }
protected void handleEnable(String healthcheck, boolean enable) throws Exception
{
if (healthcheck == null) {
throw new SolrException(SolrException.ErrorCode.SERVICE_UNAVAILABLE,
"No healthcheck file defined.");
}
File enableFile = new File(healthcheck);
if ( enable ) {
enableFile.createNewFile();
// write out when the file was created
FileWriter fw = new FileWriter(enableFile);
fw.write(formatRFC3339.format(new Date()));
fw.close();
} else {
if (enableFile.exists() && !enableFile.delete()){
throw new SolrException( SolrException.ErrorCode.NOT_FOUND,"Did not successfully delete healthcheck file:'"+healthcheck+"'");
}
}
}
//////////////////////// SolrInfoMBeans methods ////////////////////// //////////////////////// SolrInfoMBeans methods //////////////////////
@Override @Override

View File

@ -4,19 +4,19 @@
width: 49%; width: 49%;
} }
#content #dashboard #statistics #content #dashboard .fieldlist
{ {
float: left; float: left;
} }
#content #dashboard #statistics dt, #content #dashboard .fieldlist dt,
#content #dashboard #statistics dd #content #dashboard .fieldlist dd
{ {
display: block; display: block;
float: left; float: left;
} }
#content #dashboard #statistics dt #content #dashboard .fieldlist dt
{ {
clear: left; clear: left;
margin-right: 2%; margin-right: 2%;
@ -24,28 +24,28 @@
width: 23%; width: 23%;
} }
#content #dashboard #statistics dd #content #dashboard .fieldlist dd
{ {
width: 74%; width: 74%;
} }
#content #dashboard #statistics .index_optimized #content #dashboard .fieldlist .index_optimized
{ {
margin-top: 10px; margin-top: 10px;
} }
#content #dashboard #statistics .ico #content #dashboard .fieldlist .ico
{ {
background-image: url( ../../img/ico/slash.png ); background-image: url( ../../img/ico/slash.png );
height: 20px; height: 20px;
} }
#content #dashboard #statistics .ico.ico-1 #content #dashboard .fieldlist .ico.ico-1
{ {
background-image: url( ../../img/ico/tick.png ); background-image: url( ../../img/ico/tick.png );
} }
#content #dashboard #statistics .ico span #content #dashboard .fieldlist .ico span
{ {
display: none; display: none;
} }
@ -111,4 +111,17 @@
#content #dashboard #replication.is-master h2 { background-image: url( ../../img/ico/node-master.png ); } #content #dashboard #replication.is-master h2 { background-image: url( ../../img/ico/node-master.png ); }
#content #dashboard #replication.is-slave h2 { background-image: url( ../../img/ico/node-slave.png ); } #content #dashboard #replication.is-slave h2 { background-image: url( ../../img/ico/node-slave.png ); }
#content #dashboard #dataimport h2 { background-image: url( ../../img/ico/document-import.png ); } #content #dashboard #dataimport h2 { background-image: url( ../../img/ico/document-import.png ); }
#content #dashboard #admin-extra h2 { background-image: url( ../../img/ico/plus-button.png ); } #content #dashboard #admin-extra h2 { background-image: url( ../../img/ico/plus-button.png ); }
#content #dashboard #healthcheck .ico
{
background-image: url( ../../img/ico/slash.png );
height: 20px;
padding-left: 20px;
width: 60%;
}
#content #dashboard #healthcheck .ico.ico-1
{
background-image: url( ../../img/ico/tick.png );
}

View File

@ -15,6 +15,27 @@
limitations under the License. limitations under the License.
*/ */
var set_healthcheck_status = function( status )
{
var hc_button = $( '.healthcheck-status' )
if ( status == 'enable' )
{
hc_button.parents( 'dd' )
.removeClass( 'ico-0' )
.addClass( 'ico-1' );
hc_button
.addClass( 'enabled' )
.html( 'disable ping' );
} else {
hc_button.parents( 'dd' )
.removeClass( 'ico-1')
.addClass( 'ico-0' );
hc_button
.removeClass( 'enabled' )
.html( 'enable ping' );
}
};
// #/:core // #/:core
sammy.get sammy.get
( (
@ -410,8 +431,110 @@ sammy.get
} }
} }
); );
$.ajax
(
{
url : core_basepath + '/admin/ping?action=status&wt=json',
dataType : 'json',
context : $( '#healthcheck', dashboard_element ),
beforeSend : function( xhr, settings )
{
$( 'h2', this )
.addClass( 'loader' );
$( '.message', this )
.show()
.html( 'Loading' );
$( '.content', this )
.hide();
},
success : function( response, text_status, xhr )
{
$( '.message', this )
.empty()
.hide();
$( '.content', this )
.show();
var status_element = $( '.value.status', this );
var toggle_button = $( '.healthcheck-status', this );
var status = response['status'];
$( 'span', status_element ).html( status );
var action = ( response['status'] == 'enabled' ) ? 'enable' : 'disable';
set_healthcheck_status(action);
if( response['status'] == 'enabled' )
{
status_element
.addClass( 'ico-1' );
toggle_button
.addClass( 'enabled' );
}
else
{
status_element
.addClass( 'ico-0' );
}
$( '.healthcheck-status', status_element )
.die( 'click' )
.live
(
'click',
function( event )
{
var action = $(this).hasClass( 'enabled' ) ? 'disable' : 'enable';
$.ajax
(
{
url : core_basepath + '/admin/ping?action=' + action + '&wt=json',
dataType : 'json',
context : $( this ),
beforeSend : function( xhr, settings )
{
this
.addClass( 'loader' );
},
success : function( response, text_status, xhr )
{
set_healthcheck_status(action);
},
error : function( xhr, text_status, error_thrown)
{
console.warn( 'd0h, enable broken!' );
},
complete : function( xhr, text_status )
{
this
.removeClass( 'loader' );
}
}
);
}
);
},
error : function( xhr, text_status, error_thrown)
{
this
.addClass( 'disabled' );
$( '.message', this )
.show()
.html( 'Ping request handler is not configured.' );
},
complete : function( xhr, text_status )
{
$( 'h2', this )
.removeClass( 'loader' );
}
}
);
} }
); );
} }
); );

View File

@ -18,7 +18,7 @@ limitations under the License.
<div class="clearfix"> <div class="clearfix">
<div class="block" id="statistics"> <div class="block fieldlist" id="statistics">
<h2><span>Statistics</span></h2> <h2><span>Statistics</span></h2>
@ -137,5 +137,28 @@ limitations under the License.
</div> </div>
</div> </div>
<div class="block fieldlist" id="healthcheck">
<h2><span>Healthcheck</span></h2>
<div class="message-container">
<div class="message"></div>
</div>
<div class="content">
<dl>
<dt class="status">Status:</dt>
<dd class="status value ico">
<button class="healthcheck-status">Healthcheck Status</button>
</dd>
</dl>
</div>
</div>
</div>
</div> </div>