1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19 package org.apache.catalina.ant.jmx;
20
21
22 import java.util.Iterator;
23 import java.util.Set;
24
25 import javax.management.MBeanAttributeInfo;
26 import javax.management.MBeanInfo;
27 import javax.management.MBeanServerConnection;
28 import javax.management.ObjectName;
29
30 import org.apache.tools.ant.BuildException;
31
32
33 /**
34 * Query for Mbeans.
35 * <ul>
36 * <li>open no existing JSR 160 rmi jmx connection</li>
37 * <li>Get all Mbeans attributes</li>
38 * <li>Get only the Query Mbeans ObjectNames</li>
39 * <li>Show query result as Ant console log</li>
40 * <li>Bind query result as Ant properties</li>
41 * </ul>
42 * <br/>
43 * Query a list of Mbeans.
44 * <pre>
45 * <jmxQuery
46 * host="127.0.0.1"
47 * port="9014"
48 * name="Catalina:type=Manager,*
49 * resultproperty="manager" />
50 * </pre>
51 * with attribute <em>attributebinding="true"</em> you can get
52 * all attributes also from result objects.<br/>
53 * The poperty manager.lenght show the size of the result
54 * and with manager.[0..lenght].name the
55 * resulted ObjectNames are saved.
56 * These tasks require Ant 1.6 or later interface.
57 *
58 * @author Peter Rossbach
59 * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
60 * @since 5.5.10
61 */
62
63 public class JMXAccessorQueryTask extends JMXAccessorTask {
64
65 // ----------------------------------------------------- Instance Variables
66
67 private boolean attributebinding = false;
68
69 // ----------------------------------------------------- Instance Info
70
71 /**
72 * Descriptive information describing this implementation.
73 */
74 private static final String info = "org.apache.catalina.ant.JMXAccessorQueryTask/1.0";
75
76 /**
77 * Return descriptive information about this implementation and the
78 * corresponding version number, in the format
79 * <code><description>/<version></code>.
80 */
81 public String getInfo() {
82
83 return (info);
84
85 }
86
87 // ------------------------------------------------------------- Properties
88
89 /**
90 * @return Returns the attributebinding.
91 */
92 public boolean isAttributebinding() {
93 return attributebinding;
94 }
95 /**
96 * @param attributeBinding The attributebinding to set.
97 */
98 public void setAttributebinding(boolean attributeBinding) {
99 this.attributebinding = attributeBinding;
100 }
101
102 // ------------------------------------------------------ protected Methods
103
104
105 /**
106 * Execute the specified command, based on the configured properties. The
107 * input stream will be closed upon completion of this task, whether it was
108 * executed successfully or not.
109 *
110 * @exception Exception
111 * if an error occurs
112 */
113 public String jmxExecute(MBeanServerConnection jmxServerConnection)
114 throws Exception {
115
116 if (getName() == null) {
117 throw new BuildException("Must specify a 'name'");
118 }
119 return jmxQuery(jmxServerConnection, getName());
120
121 }
122
123
124 /**
125 * Call Mbean server for some mbeans with same domain, attributes.
126 * with <em>attributebindung=true</em> you can save all attributes from all found objects
127 * as your ant properties
128 * @param jmxServerConnection
129 * @param qry
130 * @return The query result
131 */
132 protected String jmxQuery(MBeanServerConnection jmxServerConnection,
133 String qry) {
134 String isError = null;
135 Set names = null;
136 String resultproperty = getResultproperty();
137 try {
138 names = jmxServerConnection.queryNames(new ObjectName(qry), null);
139 if (resultproperty != null) {
140 setProperty(resultproperty + ".Length",Integer.toString(names.size()));
141 }
142 } catch (Exception e) {
143 if (isEcho())
144 handleErrorOutput(e.getMessage());
145 return "Can't query mbeans " + qry;
146 }
147
148 if (resultproperty != null) {
149 Iterator it = names.iterator();
150 int oindex = 0;
151 String pname = null;
152 while (it.hasNext()) {
153 ObjectName oname = (ObjectName) it.next();
154 pname = resultproperty + "." + Integer.toString(oindex) + ".";
155 oindex++;
156 setProperty(pname + "Name", oname.toString());
157 if (isAttributebinding()) {
158 bindAttributes(jmxServerConnection, resultproperty, 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(MBeanServerConnection jmxServerConnection, String resultproperty, String pname, ObjectName oname) {
173 if (jmxServerConnection != null && resultproperty != null
174 && pname != null && oname != null ) {
175 try {
176 MBeanInfo minfo = jmxServerConnection.getMBeanInfo(oname);
177 String code = minfo.getClassName();
178 if ("org.apache.tomcat.util.modeler.BaseModelMBean".equals(code)) {
179 code = (String) jmxServerConnection.getAttribute(oname,
180 "modelerType");
181 }
182 MBeanAttributeInfo attrs[] = minfo.getAttributes();
183 Object value = null;
184
185 for (int i = 0; i < attrs.length; i++) {
186 if (!attrs[i].isReadable())
187 continue;
188 String attName = attrs[i].getName();
189 if (attName.indexOf("=") >= 0 || attName.indexOf(":") >= 0
190 || attName.indexOf(" ") >= 0) {
191 continue;
192 }
193
194 try {
195 value = jmxServerConnection
196 .getAttribute(oname, attName);
197 } catch (Throwable t) {
198 if (isEcho())
199 handleErrorOutput("Error getting attribute "
200 + oname + " " + pname + attName + " "
201 + t.toString());
202 continue;
203 }
204 if (value == null)
205 continue;
206 if ("modelerType".equals(attName))
207 continue;
208 createProperty(pname + attName, value);
209 }
210 } catch (Exception e) {
211 // Ignore
212 }
213 }
214 }
215 }