001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.catalina.ant.jmx;
019:
020: import java.util.Iterator;
021: import java.util.Set;
022:
023: import javax.management.MBeanAttributeInfo;
024: import javax.management.MBeanInfo;
025: import javax.management.MBeanServerConnection;
026: import javax.management.ObjectName;
027:
028: import org.apache.tools.ant.BuildException;
029:
030: /**
031: * Query for Mbeans.
032: * <ul>
033: * <li>open no existing JSR 160 rmi jmx connection</li>
034: * <li>Get all Mbeans attributes</li>
035: * <li>Get only the Query Mbeans ObjectNames</li>
036: * <li>Show query result as Ant console log</li>
037: * <li>Bind query result as Ant properties</li>
038: * </ul>
039: * <br/>
040: * Query a list of Mbeans.
041: * <pre>
042: * <jmxQuery
043: * host="127.0.0.1"
044: * port="9014"
045: * name="Catalina:type=Manager,*
046: * resultproperty="manager" />
047: * </pre>
048: * with attribute <em>attributebinding="true"</em> you can get
049: * all attributes also from result objects.<br/>
050: * The poperty manager.lenght show the size of the result
051: * and with manager.[0..lenght].name the
052: * resulted ObjectNames are saved.
053: * These tasks require Ant 1.6 or later interface.
054: *
055: * @author Peter Rossbach
056: * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
057: * @since 5.5.10
058: */
059:
060: public class JMXAccessorQueryTask extends JMXAccessorTask {
061:
062: // ----------------------------------------------------- Instance Variables
063:
064: private boolean attributebinding = false;
065:
066: // ----------------------------------------------------- Instance Info
067:
068: /**
069: * Descriptive information describing this implementation.
070: */
071: private static final String info = "org.apache.catalina.ant.JMXAccessorQueryTask/1.0";
072:
073: /**
074: * Return descriptive information about this implementation and the
075: * corresponding version number, in the format
076: * <code><description>/<version></code>.
077: */
078: public String getInfo() {
079:
080: return (info);
081:
082: }
083:
084: // ------------------------------------------------------------- Properties
085:
086: /**
087: * @return Returns the attributebinding.
088: */
089: public boolean isAttributebinding() {
090: return attributebinding;
091: }
092:
093: /**
094: * @param attributeBinding The attributebinding to set.
095: */
096: public void setAttributebinding(boolean attributeBinding) {
097: this .attributebinding = attributeBinding;
098: }
099:
100: // ------------------------------------------------------ protected Methods
101:
102: /**
103: * Execute the specified command, based on the configured properties. The
104: * input stream will be closed upon completion of this task, whether it was
105: * executed successfully or not.
106: *
107: * @exception Exception
108: * if an error occurs
109: */
110: public String jmxExecute(MBeanServerConnection jmxServerConnection)
111: throws Exception {
112:
113: if (getName() == null) {
114: throw new BuildException("Must specify a 'name'");
115: }
116: return jmxQuery(jmxServerConnection, getName());
117:
118: }
119:
120: /**
121: * Call Mbean server for some mbeans with same domain, attributes.
122: * with <em>attributebindung=true</em> you can save all attributes from all found objects
123: * as your ant properties
124: * @param jmxServerConnection
125: * @param qry
126: * @return The query result
127: */
128: protected String jmxQuery(
129: MBeanServerConnection jmxServerConnection, String qry) {
130: String isError = null;
131: Set names = null;
132: String resultproperty = getResultproperty();
133: try {
134: names = jmxServerConnection.queryNames(new ObjectName(qry),
135: null);
136: if (resultproperty != null) {
137: setProperty(resultproperty + ".Length", Integer
138: .toString(names.size()));
139: }
140: } catch (Exception e) {
141: if (isEcho())
142: handleErrorOutput(e.getMessage());
143: return "Can't query mbeans " + qry;
144: }
145:
146: if (resultproperty != null) {
147: Iterator it = names.iterator();
148: int oindex = 0;
149: String pname = null;
150: while (it.hasNext()) {
151: ObjectName oname = (ObjectName) it.next();
152: pname = resultproperty + "." + Integer.toString(oindex)
153: + ".";
154: oindex++;
155: setProperty(pname + "Name", oname.toString());
156: if (isAttributebinding()) {
157: bindAttributes(jmxServerConnection, resultproperty,
158: pname, oname);
159:
160: }
161: }
162: }
163: return isError;
164: }
165:
166: /**
167: * @param jmxServerConnection
168: * @param resultproperty
169: * @param pname
170: * @param oname
171: */
172: protected void bindAttributes(
173: MBeanServerConnection jmxServerConnection,
174: String resultproperty, String pname, ObjectName oname) {
175: if (jmxServerConnection != null && resultproperty != null
176: && pname != null && oname != null) {
177: try {
178: MBeanInfo minfo = jmxServerConnection
179: .getMBeanInfo(oname);
180: String code = minfo.getClassName();
181: if ("org.apache.tomcat.util.modeler.BaseModelMBean"
182: .equals(code)) {
183: code = (String) jmxServerConnection.getAttribute(
184: oname, "modelerType");
185: }
186: MBeanAttributeInfo attrs[] = minfo.getAttributes();
187: Object value = null;
188:
189: for (int i = 0; i < attrs.length; i++) {
190: if (!attrs[i].isReadable())
191: continue;
192: String attName = attrs[i].getName();
193: if (attName.indexOf("=") >= 0
194: || attName.indexOf(":") >= 0
195: || attName.indexOf(" ") >= 0) {
196: continue;
197: }
198:
199: try {
200: value = jmxServerConnection.getAttribute(oname,
201: attName);
202: } catch (Throwable t) {
203: if (isEcho())
204: handleErrorOutput("Error getting attribute "
205: + oname
206: + " "
207: + pname
208: + attName
209: + " " + t.toString());
210: continue;
211: }
212: if (value == null)
213: continue;
214: if ("modelerType".equals(attName))
215: continue;
216: createProperty(pname + attName, value);
217: }
218: } catch (Exception e) {
219: // Ignore
220: }
221: }
222: }
223: }
|