blob: 4b24589d89895674dc596240722e74f2c845ad1f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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.apache.jk.status;
import java.util.Iterator;
import java.util.List;
import org.apache.catalina.ant.BaseRedirectorHelperTask;
import org.apache.tomcat.util.IntrospectionUtils;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
/**
* Ant task that implements the show <code>/jkstatus</code> command, supported
* by the mod_jk status (1.2.13) application.
*
* @author Peter Rossbach
* @version $Revision$
* @since 5.5.10
*/
public class JkStatusTask extends BaseRedirectorHelperTask {
/**
* The descriptive information about this implementation.
*/
private static final String info = "org.apache.jk.status.JkStatusTask/1.2";
/**
* Store status as <code>resultProperty</code> prefix.
*/
protected String resultproperty;
/**
* Echo status at ant console
*/
protected boolean echo = false;
/**
* The login password for the <code>mod_jk status</code> page.
*/
protected String password = null;
/**
* The URL of the <code>mod_jk status</code> page to be used.
*/
protected String url = "http://localhost:80/jkstatus";
/**
* The login username for the <code>mod_jk status</code> page.
*/
protected String username = null;
private String errorProperty;
private String worker;
private String loadbalancer;
/**
* Return descriptive information about this implementation and the
* corresponding version number, in the format
* <code>&lt;description&gt;/&lt;version&gt;</code>.
*/
public String getInfo() {
return (info);
}
public String getPassword() {
return (this.password);
}
public void setPassword(String password) {
this.password = password;
}
public String getUrl() {
return (this.url);
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return (this.username);
}
public void setUsername(String username) {
this.username = username;
}
/**
* @return Returns the echo.
*/
public boolean isEcho() {
return echo;
}
/**
* @param echo
* The echo to set.
*/
public void setEcho(boolean echo) {
this.echo = echo;
}
/**
* @return Returns the resultproperty.
*/
public String getResultproperty() {
return resultproperty;
}
/**
* @param resultproperty
* The resultproperty to set.
*/
public void setResultproperty(String resultproperty) {
this.resultproperty = resultproperty;
}
/**
* @return Returns the loadbalancer.
*/
public String getLoadbalancer() {
return loadbalancer;
}
/**
* @param loadbalancer The loadbalancer to set.
*/
public void setLoadbalancer(String loadbalancer) {
this.loadbalancer = loadbalancer;
}
/**
* @return Returns the worker.
*/
public String getWorker() {
return worker;
}
/**
* @param worker The worker to set.
*/
public void setWorker(String worker) {
this.worker = worker;
}
// --------------------------------------------------------- Public Methods
/**
* Get jkstatus from server.
*
* @exception BuildException
* if a validation error occurs
*/
public void execute() throws BuildException {
if (url == null) {
throw new BuildException("Must specify an 'url'");
}
boolean isWorkerOnly = worker != null && !"".equals(worker);
boolean isLoadbalancerOnly = loadbalancer != null
&& !"".equals(loadbalancer);
StringBuffer error = new StringBuffer();
try {
JkStatusAccessor accessor = new JkStatusAccessor();
JkStatus status = accessor.status(url, username, password);
if (status.result != null && !"OK".equals(status.result.type) ) {
if (getErrorProperty() != null) {
getProject().setNewProperty(errorProperty, status.result.message);
}
if (isFailOnError()) {
throw new BuildException(status.result.message);
} else {
handleErrorOutput(status.result.message);
return;
}
}
if (!isWorkerOnly && !isLoadbalancerOnly) {
JkServer server = status.getServer();
JkSoftware software = status.getSoftware();
JkResult result = status.getResult();
if (resultproperty != null) {
createProperty(server, "server", "name");
createProperty(server, "server", "port");
createProperty(software, "web_server");
createProperty(software, "jk_version");
createProperty(result, "result", "type");
createProperty(result, "result", "message");
}
if (isEcho()) {
handleOutput("server name=" + server.getName() + ":"
+ server.getPort() + " - " + software.getWeb_server() + " - " + software.getJk_version());
}
}
List balancers = status.getBalancers();
for (Iterator iter = balancers.iterator(); iter.hasNext();) {
JkBalancer balancer = (JkBalancer) iter.next();
String balancerIndex = null;
if (isLoadbalancerOnly) {
if (loadbalancer.equals(balancer.getName())) {
if (resultproperty != null) {
setPropertyBalancerOnly(balancer);
}
echoBalancer(balancer);
return;
}
} else {
if (!isWorkerOnly) {
if (resultproperty != null) {
if ( balancer.getId() >= 0)
balancerIndex = Integer.toString(balancer.getId());
else
balancerIndex = balancer.getName() ;
setPropertyBalancer(balancer,balancerIndex);
}
echoBalancer(balancer);
}
List members = balancer.getBalancerMembers();
for (Iterator iterator = members.iterator(); iterator
.hasNext();) {
JkBalancerMember member = (JkBalancerMember) iterator
.next();
if (isWorkerOnly) {
if (worker.equals(member.getName())) {
if (resultproperty != null) {
setPropertyWorkerOnly(balancer, member);
}
echoWorker(member);
return;
}
} else {
if (resultproperty != null) {
setPropertyWorker(null, member);
}
echoWorker(member);
if (member.getStatus() != null && !"OK".equals(member.getStatus())) {
error.append(" worker name=" + member.getName()
+ " status=" + member.getStatus()
+ " host=" + member.getAddress());
}
if (member.getState() != null && !("OK".equals(member.getState()) || "N/A".equals(member.getState())) ){
error.append(" worker name=" + member.getName()
+ " state=" + member.getState()
+ " host=" + member.getAddress());
}
}
}
if (!isWorkerOnly) {
if (resultproperty != null && members.size() > 0) {
getProject().setNewProperty(
resultproperty + "."
+ balancer.getName() + ".length",
Integer.toString(members.size()));
}
List mappings = balancer.getBalancerMappings();
int j = 0;
String mapIndex ;
if( balancerIndex != null )
mapIndex = balancerIndex + ".map" ;
else
mapIndex = "map" ;
for (Iterator iterator = mappings.iterator(); iterator
.hasNext(); j++) {
JkBalancerMapping mapping = (JkBalancerMapping) iterator
.next();
if (resultproperty != null) {
String stringIndex2 ;
if( mapping.getId() >= 0) {
stringIndex2 = Integer.toString(mapping.getId()) ;
} else {
stringIndex2 = Integer.toString(j);
}
createProperty(mapping, mapIndex,
stringIndex2, "type");
createProperty(mapping, mapIndex,
stringIndex2, "uri");
createProperty(mapping, mapIndex,
stringIndex2, "context");
createProperty(mapping, mapIndex,
stringIndex2, "source");
}
if (isEcho()) {
String mappingOut ;
if(mapping.source != null) {
mappingOut =
"balancer name="
+ balancer.getName() + " mappingtype="
+ mapping.getType() + " uri="
+ mapping.getUri() + " source="
+ mapping.getSource() ;
} else {
mappingOut = "balancer name="
+ balancer.getName() + " mappingtype="
+ mapping.getType() + " uri="
+ mapping.getUri() + " context="
+ mapping.getContext() ;
}
handleOutput(mappingOut);
}
}
if (resultproperty != null && mappings.size() > 0) {
getProject().setNewProperty(
resultproperty + "."
+ mapIndex + ".length",
Integer.toString(mappings.size()));
}
}
}
}
if (!isWorkerOnly && !isLoadbalancerOnly) {
if (resultproperty != null && balancers.size() > 0) {
getProject().setNewProperty(
resultproperty + ".length",
Integer.toString(balancers.size()));
}
}
} catch (Throwable t) {
error.append(t.getMessage());
if (getErrorProperty() != null) {
getProject().setNewProperty(errorProperty, error.toString());
}
if (isFailOnError()) {
throw new BuildException(t);
} else {
handleErrorOutput(t.getMessage());
return;
}
}
if (error.length() != 0) {
if (getErrorProperty() != null) {
getProject().setNewProperty(errorProperty, error.toString());
}
if (isFailOnError()) {
// exception should be thrown only if failOnError == true
// or error line will be logged twice
throw new BuildException(error.toString());
}
}
}
/**
* @param member
*/
private void echoWorker(JkBalancerMember member) {
if (isEcho()) {
StringBuffer state = new StringBuffer("worker name=") ;
state.append( member.getName()) ;
if(member.getStatus() != null) {
state.append(" status=");
state.append(member.getStatus());
}
if(member.getState() != null) {
state.append(" state=");
state.append(member.getState()) ;
}
state.append(" host=");
state.append(member.getAddress());
handleOutput(state.toString());
}
}
/**
* @param balancer
*/
private void echoBalancer(JkBalancer balancer) {
if (isEcho()) {
handleOutput("balancer name=" + balancer.getName() + " type="
+ balancer.getType());
}
}
/**
* @param balancer
*/
private void setPropertyBalancerOnly(JkBalancer balancer) {
String prefix = resultproperty + "." + balancer.getName();
if(balancer.getId() >= 0 ) {
getProject().setNewProperty(prefix + ".id",
Integer.toString(balancer.getId()));
}
getProject().setNewProperty(prefix + ".type", balancer.getType());
getProject().setNewProperty(prefix + ".stick_session",
Boolean.toString(balancer.isSticky_session()));
getProject().setNewProperty(prefix + ".sticky_session_force",
Boolean.toString(balancer.isSticky_session_force()));
getProject().setNewProperty(prefix + ".retries",
Integer.toString(balancer.getRetries()));
getProject().setNewProperty(prefix + ".recover_time",
Integer.toString(balancer.getRecover_time()));
getProject().setNewProperty(prefix + ".method",
balancer.getMethod());
getProject().setNewProperty(prefix + ".good",
Integer.toString(balancer.getGood()));
getProject().setNewProperty(prefix + ".degraded",
Integer.toString(balancer.getDegraded()));
getProject().setNewProperty(prefix + ".bad",
Integer.toString(balancer.getBad()));
getProject().setNewProperty(prefix + ".busy",
Integer.toString(balancer.getBusy()));
getProject().setNewProperty(prefix + ".map_count",
Integer.toString(balancer.getMap_count()));
getProject().setNewProperty(prefix + ".member_count",
Integer.toString(balancer.getMember_count()));
getProject().setNewProperty(prefix + ".max_busy",
Integer.toString(balancer.getMax_busy()));
getProject().setNewProperty(prefix + ".time_to_maintenance_min",
Integer.toString(balancer.getTime_to_maintenance_min()));
getProject().setNewProperty(prefix + ".time_to_maintenance_max",
Integer.toString(balancer.getTime_to_maintenance_max()));
getProject().setNewProperty(prefix + ".lock",
balancer.getLock());
}
/**
* @param balancer
* @return
*/
private void setPropertyBalancer(JkBalancer balancer,String balancerIndex) {
if(balancer.id >= 0) {
createProperty(balancer, balancerIndex, "id");
}
createProperty(balancer, balancerIndex, "name");
createProperty(balancer, balancerIndex, "type");
createProperty(balancer, balancerIndex, "sticky_session");
createProperty(balancer, balancerIndex, "sticky_session_force");
createProperty(balancer, balancerIndex, "retries");
createProperty(balancer, balancerIndex, "recover_time");
if(balancer.getMethod() != null) {
createProperty(balancer, balancerIndex, "method");
}
if(balancer.getLock() != null) {
createProperty(balancer, balancerIndex, "lock");
}
if(balancer.getGood() >= 0) {
createProperty(balancer, balancerIndex, "good");
}
if(balancer.getDegraded() >= 0) {
createProperty(balancer, balancerIndex, "degraded");
}
if(balancer.getBad() >= 0) {
createProperty(balancer, balancerIndex, "bad");
}
if(balancer.getBusy() >= 0) {
createProperty(balancer, balancerIndex, "busy");
}
if(balancer.getMax_busy() >= 0) {
createProperty(balancer, balancerIndex, "max_busy");
}
if(balancer.getMember_count() >=0) {
createProperty(balancer, balancerIndex, "member_count");
}
if(balancer.getMap_count() >=0) {
createProperty(balancer, balancerIndex, "map_count");
}
if(balancer.getTime_to_maintenance_min() >=0) {
createProperty(balancer, balancerIndex, "time_to_maintenance_min");
}
if(balancer.getTime_to_maintenance_max() >=0) {
createProperty(balancer, balancerIndex, "time_to_maintenance_max");
}
}
/**
* @param balancerIndex
* @param member
*/
private void setPropertyWorker(String balancerIndex, JkBalancerMember member) {
String workerIndex ;
if(member.getId() >= 0) {
workerIndex = Integer.toString(member.getId());
createProperty(member, balancerIndex, workerIndex, "id");
createProperty(member, balancerIndex, workerIndex, "name");
} else {
workerIndex = member.getName();
}
createProperty(member, balancerIndex, workerIndex, "type");
createProperty(member, balancerIndex, workerIndex, "host");
createProperty(member, balancerIndex, workerIndex, "port");
createProperty(member, balancerIndex, workerIndex, "address");
if(member.getJvm_route() != null) {
createProperty(member, balancerIndex, workerIndex, "jvm_route");
}
if(member.getRoute() != null) {
createProperty(member, balancerIndex, workerIndex, "route");
}
if(member.getStatus() != null) {
createProperty(member, balancerIndex, workerIndex, "status");
}
if(member.getActivation() != null) {
createProperty(member, balancerIndex, workerIndex, "activation");
}
if(member.getState() != null) {
createProperty(member, balancerIndex, workerIndex, "state");
}
createProperty(member, balancerIndex, workerIndex, "lbfactor");
createProperty(member, balancerIndex, workerIndex, "lbvalue");
if(member.getLbmult() >= 0) {
createProperty(member, balancerIndex, workerIndex, "lbmult");
}
createProperty(member, balancerIndex, workerIndex, "elected");
createProperty(member, balancerIndex, workerIndex, "readed");
createProperty(member, balancerIndex, workerIndex, "busy");
if(member.getMax_busy() >= 0) {
createProperty(member, balancerIndex, workerIndex, "max_busy");
}
createProperty(member, balancerIndex, workerIndex, "transferred");
createProperty(member, balancerIndex, workerIndex, "errors");
if(member.getClient_errors() >= 0) {
createProperty(member, balancerIndex, workerIndex, "client_errors");
}
if(member.getDistance() >= 0) {
createProperty(member, balancerIndex, workerIndex, "distance");
}
if (member.getDomain() != null) {
createProperty(member, balancerIndex, workerIndex, "domain");
} else {
getProject().setNewProperty(resultproperty + "." + balancerIndex + "." + workerIndex +
".domain", "");
}
if (member.getRedirect() != null) {
createProperty(member, balancerIndex, workerIndex, "redirect");
} else {
getProject().setNewProperty(resultproperty + "." + balancerIndex + "." + workerIndex +
".redirect", "");
}
}
/**
* @param balancer
* @param member
*/
private void setPropertyWorkerOnly(JkBalancer balancer,
JkBalancerMember member) {
//String prefix = resultproperty + "." + balancer.getName() + "." + member.getName();
String prefix = resultproperty + "." + member.getName();
Project currentProject = getProject();
if ( balancer.getId() >= 0) {
currentProject.setNewProperty(prefix + ".lb.id",
Integer.toString(balancer.getId()));
}
//currentProject.setNewProperty(prefix + ".lb.name", balancer.getName());
if( member.getId() >= 0) {
currentProject.setNewProperty(prefix + ".id",
Integer.toString(member.getId()));
}
currentProject.setNewProperty(prefix + ".type", member.getType());
if (member.getJvm_route() != null) {
currentProject.setNewProperty(prefix + ".jvm_route", member.getJvm_route());
}
if (member.getRoute() != null) {
currentProject.setNewProperty(prefix + ".route", member.getRoute());
}
if (member.getStatus() != null) {
currentProject.setNewProperty(prefix + ".status", member.getStatus());
}
if (member.getActivation() != null) {
currentProject.setNewProperty(prefix + ".activation", member.getActivation());
}
if (member.getState() != null) {
currentProject.setNewProperty(prefix + ".state", member.getState());
}
currentProject.setNewProperty(prefix + ".host", member.getHost());
currentProject.setNewProperty(prefix + ".address", member.getAddress());
currentProject.setNewProperty(prefix + ".port",
Integer.toString(member.getPort()));
currentProject.setNewProperty(prefix + ".lbfactor",
Integer.toString(member.getLbfactor()));
currentProject.setNewProperty(prefix + ".lbvalue",
Long.toString(member.getLbvalue()));
if(member.getLbmult() >= 0) {
currentProject.setNewProperty(prefix + ".lbmult",
Long.toString(member.getLbmult()));
}
currentProject.setNewProperty(prefix + ".elected",
Long.toString(member.getElected()));
currentProject.setNewProperty(prefix + ".readed",
Long.toString(member.getReaded()));
currentProject.setNewProperty(prefix + ".transferred",
Long.toString(member.getTransferred()));
currentProject.setNewProperty(prefix + ".busy",
Integer.toString(member.getBusy()));
if(member.getMax_busy() >= 0) {
currentProject.setNewProperty(prefix + ".max_busy",
Long.toString(member.getMax_busy()));
}
currentProject.setNewProperty(prefix + ".errors",
Long.toString(member.getErrors()));
if(member.getClient_errors() >= 0) {
currentProject.setNewProperty(prefix + ".client_errors",
Long.toString(member.getClient_errors()));
}
if(member.getDistance() >= 0) {
currentProject.setNewProperty(prefix + ".distance",
Integer.toString(member.getDistance()));
}
if (member.getDomain() != null) {
currentProject.setNewProperty(prefix + ".domain", member.getDomain());
} else {
currentProject.setNewProperty(prefix + ".domain", "");
}
if (member.getRedirect() != null) {
currentProject.setNewProperty(prefix + ".redirect",
member.getRedirect());
} else {
currentProject.setNewProperty(prefix + ".redirect", "");
}
if(member.getTime_to_recover() >= 0) {
currentProject.setNewProperty(prefix + ".time_to_recover",
Integer.toString(member.getTime_to_recover()));
}
if(member.getTime_to_recover_min() >= 0) {
currentProject.setNewProperty(prefix + ".time_to_recover_min",
Integer.toString(member.getTime_to_recover_min()));
}
if(member.getTime_to_recover_max() >= 0) {
currentProject.setNewProperty(prefix + ".time_to_recover_max",
Integer.toString(member.getTime_to_recover_max()));
currentProject.setNewProperty(prefix + ".time_to_recover",
(Integer.toString((member.getTime_to_recover_min()
+ member.getTime_to_recover_max()) / 2)));
}
}
/*
* Set ant property for save error state
*
* @see org.apache.catalina.ant.BaseRedirectorHelperTask#setErrorProperty(java.lang.String)
*/
public void setErrorProperty(String arg0) {
errorProperty = arg0;
super.setErrorProperty(arg0);
}
/**
* @return Returns the errorProperty.
*/
public String getErrorProperty() {
return errorProperty;
}
protected void createProperty(Object result, String attribute) {
createProperty(result, null, null, attribute);
}
protected void createProperty(Object result, String arraymark,
String attribute) {
createProperty(result, arraymark, null, attribute);
}
/**
* create result as property with name from attribute resultproperty
*/
protected void createProperty(Object result, String arraymark,
String arraymark2, String attribute) {
if (resultproperty != null) {
Object value = IntrospectionUtils.getProperty(result, attribute);
if (value != null ) {
StringBuffer propertyname = new StringBuffer(resultproperty);
if (result instanceof JkBalancer) {
if (arraymark != null) {
propertyname.append(".");
propertyname.append(arraymark);
}
} else if (result instanceof JkServer) {
if (arraymark != null) {
propertyname.append(".");
propertyname.append(arraymark);
}
} else if (result instanceof JkSoftware) {
if (arraymark != null) {
propertyname.append(".");
propertyname.append(arraymark);
}
} else if (result instanceof JkResult) {
if (arraymark != null) {
propertyname.append(".");
propertyname.append(arraymark);
}
} else if (result instanceof JkBalancerMember) {
if (arraymark != null) {
propertyname.append(".");
propertyname.append(arraymark);
}
if (arraymark2 != null) {
propertyname.append(".");
propertyname.append(arraymark2);
}
} else if (result instanceof JkBalancerMapping) {
if (arraymark != null) {
propertyname.append(".");
propertyname.append(arraymark);
}
if (arraymark2 != null) {
propertyname.append(".");
propertyname.append(arraymark2);
}
}
propertyname.append(".");
propertyname.append(attribute);
getProject().setNewProperty(propertyname.toString(),
value.toString());
}
}
}
}