blob: 6c801c97eec4061e965077bab670c52366d11bd9 [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.catalina.ant.jmx;
import java.util.Iterator;
import java.util.Set;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import org.apache.tools.ant.BuildException;
/**
* Query for Mbeans.
* <ul>
* <li>open no existing JSR 160 rmi jmx connection</li>
* <li>Get all Mbeans attributes</li>
* <li>Get only the Query Mbeans ObjectNames</li>
* <li>Show query result as Ant console log</li>
* <li>Bind query result as Ant properties</li>
* </ul>
* <br/>
* Query a list of Mbeans.
* <pre>
* &lt;jmxQuery
* host="127.0.0.1"
* port="9014"
* name="Catalina:type=Manager,*
* resultproperty="manager" /&gt;
* </pre>
* with attribute <em>attributebinding="true"</em> you can get
* all attributes also from result objects.<br/>
* The poperty manager.lenght show the size of the result
* and with manager.[0..lenght].name the
* resulted ObjectNames are saved.
* These tasks require Ant 1.6 or later interface.
*
* @author Peter Rossbach
* @version $Revision$ $Date$
* @since 5.5.10
*/
public class JMXAccessorQueryTask extends JMXAccessorTask {
// ----------------------------------------------------- Instance Variables
private boolean attributebinding = false;
// ----------------------------------------------------- Instance Info
/**
* Descriptive information describing this implementation.
*/
private static final String info = "org.apache.catalina.ant.JMXAccessorQueryTask/1.0";
/**
* 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);
}
// ------------------------------------------------------------- Properties
/**
* @return Returns the attributebinding.
*/
public boolean isAttributebinding() {
return attributebinding;
}
/**
* @param attributeBinding The attributebinding to set.
*/
public void setAttributebinding(boolean attributeBinding) {
this.attributebinding = attributeBinding;
}
// ------------------------------------------------------ protected Methods
/**
* Execute the specified command, based on the configured properties. The
* input stream will be closed upon completion of this task, whether it was
* executed successfully or not.
*
* @exception Exception
* if an error occurs
*/
public String jmxExecute(MBeanServerConnection jmxServerConnection)
throws Exception {
if (getName() == null) {
throw new BuildException("Must specify a 'name'");
}
return jmxQuery(jmxServerConnection, getName());
}
/**
* Call Mbean server for some mbeans with same domain, attributes.
* with <em>attributebindung=true</em> you can save all attributes from all found objects
* as your ant properties
* @param jmxServerConnection
* @param qry
* @return The query result
*/
protected String jmxQuery(MBeanServerConnection jmxServerConnection,
String qry) {
String isError = null;
Set names = null;
String resultproperty = getResultproperty();
try {
names = jmxServerConnection.queryNames(new ObjectName(qry), null);
if (resultproperty != null) {
setProperty(resultproperty + ".Length",Integer.toString(names.size()));
}
} catch (Exception e) {
if (isEcho())
handleErrorOutput(e.getMessage());
return "Can't query mbeans " + qry;
}
if (resultproperty != null) {
Iterator it = names.iterator();
int oindex = 0;
String pname = null;
while (it.hasNext()) {
ObjectName oname = (ObjectName) it.next();
pname = resultproperty + "." + Integer.toString(oindex) + ".";
oindex++;
setProperty(pname + "Name", oname.toString());
if (isAttributebinding()) {
bindAttributes(jmxServerConnection, resultproperty, pname, oname);
}
}
}
return isError;
}
/**
* @param jmxServerConnection
* @param resultproperty
* @param pname
* @param oname
*/
protected void bindAttributes(MBeanServerConnection jmxServerConnection, String resultproperty, String pname, ObjectName oname) {
if (jmxServerConnection != null && resultproperty != null
&& pname != null && oname != null ) {
try {
MBeanInfo minfo = jmxServerConnection.getMBeanInfo(oname);
String code = minfo.getClassName();
if ("org.apache.commons.modeler.BaseModelMBean".equals(code)) {
code = (String) jmxServerConnection.getAttribute(oname,
"modelerType");
}
MBeanAttributeInfo attrs[] = minfo.getAttributes();
Object value = null;
for (int i = 0; i < attrs.length; i++) {
if (!attrs[i].isReadable())
continue;
String attName = attrs[i].getName();
if (attName.indexOf("=") >= 0 || attName.indexOf(":") >= 0
|| attName.indexOf(" ") >= 0) {
continue;
}
try {
value = jmxServerConnection
.getAttribute(oname, attName);
} catch (Throwable t) {
if (isEcho())
handleErrorOutput("Error getting attribute "
+ oname + " " + pname + attName + " "
+ t.toString());
continue;
}
if (value == null)
continue;
if ("modelerType".equals(attName))
continue;
createProperty(pname + attName, value);
}
} catch (Exception e) {
// Ignore
}
}
}
}