KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > ant > jmx > JMXAccessorTask


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 package org.apache.catalina.ant.jmx;
19
20 import java.io.IOException JavaDoc;
21 import java.lang.reflect.Array JavaDoc;
22 import java.net.InetAddress JavaDoc;
23 import java.net.MalformedURLException JavaDoc;
24 import java.net.UnknownHostException JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Properties JavaDoc;
30 import java.util.Set JavaDoc;
31 import java.util.StringTokenizer JavaDoc;
32
33 import javax.management.MBeanServerConnection JavaDoc;
34 import javax.management.MalformedObjectNameException JavaDoc;
35 import javax.management.ObjectName JavaDoc;
36 import javax.management.openmbean.CompositeData JavaDoc;
37 import javax.management.openmbean.CompositeDataSupport JavaDoc;
38 import javax.management.openmbean.CompositeType JavaDoc;
39 import javax.management.openmbean.OpenType JavaDoc;
40 import javax.management.openmbean.SimpleType JavaDoc;
41 import javax.management.openmbean.TabularDataSupport JavaDoc;
42 import javax.management.remote.JMXConnector JavaDoc;
43 import javax.management.remote.JMXConnectorFactory JavaDoc;
44 import javax.management.remote.JMXServiceURL JavaDoc;
45
46 import org.apache.catalina.ant.BaseRedirectorHelperTask;
47 import org.apache.tools.ant.BuildException;
48 import org.apache.tools.ant.Project;
49
50 /**
51  * Access <em>JMX</em> JSR 160 MBeans Server.
52  * <ul>
53  * <li>open more then one JSR 160 rmi connection</li>
54  * <li>Get/Set Mbeans attributes</li>
55  * <li>Call Mbean Operation with arguments</li>
56  * <li>Argument values can be converted from string to
57  * int,long,float,double,boolean,ObjectName or InetAddress</li>
58  * <li>Query Mbeans</li>
59  * <li>Show Get, Call, Query result at Ant console log</li>
60  * <li>Bind Get, Call, Query result at Ant properties</li>
61  * </ul>
62  *
63  * Examples: open server with reference and autorisation
64  *
65  * <pre>
66  *
67  * &lt;jmxOpen
68  * host=&quot;127.0.0.1&quot;
69  * port=&quot;9014&quot;
70  * username=&quot;monitorRole&quot;
71  * password=&quot;mysecret&quot;
72  * ref=&quot;jmx.myserver&quot;
73  * /&gt;
74  *
75  * </pre>
76  *
77  * All calls after opening with same refid reuse the connection.
78  * <p>
79  * First call to a remote MBeanserver save the JMXConnection a referenz
80  * <em>jmx.server</em>
81  * </p>
82  * All JMXAccessorXXXTask support the attribute <em>if</em> and
83  * <em>unless</em>. With <em>if</em> the task is only execute when property
84  * exist and with <em>unless</em> when property not exists. <br/><b>NOTE
85  * </b>: These tasks require Ant 1.6 or later interface.
86  *
87  * @author Peter Rossbach
88  * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
89  * @since 5.5.10
90  */

91
92 public class JMXAccessorTask extends BaseRedirectorHelperTask {
93
94     // ----------------------------------------------------- Instance Variables
95

96     public static String JavaDoc JMX_SERVICE_PREFIX = "service:jmx:rmi:///jndi/rmi://";
97
98     public static String JavaDoc JMX_SERVICE_SUFFIX = "/jmxrmi";
99
100     private String JavaDoc name = null;
101
102     private String JavaDoc resultproperty;
103
104     private String JavaDoc url = null;
105
106     private String JavaDoc host = "localhost";
107
108     private String JavaDoc port = "8050";
109
110     private String JavaDoc password = null;
111
112     private String JavaDoc username = null;
113
114     private String JavaDoc ref = "jmx.server";
115
116     private boolean echo = false;
117
118     private boolean separatearrayresults = true;
119
120     private String JavaDoc delimiter;
121
122     private String JavaDoc unlessCondition;
123
124     private String JavaDoc ifCondition;
125
126     private Properties JavaDoc properties = new Properties JavaDoc();
127
128     // ----------------------------------------------------- Instance Info
129

130     /**
131      * Descriptive information describing this implementation.
132      */

133     private static final String JavaDoc info = "org.apache.catalina.ant.JMXAccessorTask/1.1";
134
135     /**
136      * Return descriptive information about this implementation and the
137      * corresponding version number, in the format
138      * <code>&lt;description&gt;/&lt;version&gt;</code>.
139      */

140     public String JavaDoc getInfo() {
141
142         return (info);
143
144     }
145
146     // ------------------------------------------------------------- Properties
147

148     /**
149      * The name used at remote MbeanServer
150      */

151
152     public String JavaDoc getName() {
153         return (this.name);
154     }
155
156     public void setName(String JavaDoc objectName) {
157         this.name = objectName;
158     }
159
160     /**
161      * @return Returns the resultproperty.
162      */

163     public String JavaDoc getResultproperty() {
164         return resultproperty;
165     }
166
167     /**
168      * @param propertyName The resultproperty to set.
169      */

170     public void setResultproperty(String JavaDoc propertyName) {
171         this.resultproperty = propertyName;
172     }
173
174     /**
175      * @return Returns the delimiter.
176      */

177     public String JavaDoc getDelimiter() {
178         return delimiter;
179     }
180
181     /**
182      * @param separator The delimiter to set.
183      */

184     public void setDelimiter(String JavaDoc separator) {
185         this.delimiter = separator;
186     }
187
188     /**
189      * @return Returns the echo.
190      */

191     public boolean isEcho() {
192         return echo;
193     }
194
195     /**
196      * @param echo
197      * The echo to set.
198      */

199     public void setEcho(boolean echo) {
200         this.echo = echo;
201     }
202
203     /**
204      * @return Returns the separatearrayresults.
205      */

206     public boolean isSeparatearrayresults() {
207         return separatearrayresults;
208     }
209
210     /**
211      * @param separateArrayResults
212      * The separatearrayresults to set.
213      */

214     public void setSeparatearrayresults(boolean separateArrayResults) {
215         this.separatearrayresults = separateArrayResults;
216     }
217
218     /**
219      * The login password for the <code>Manager</code> application.
220      */

221     public String JavaDoc getPassword() {
222         return (this.password);
223     }
224
225     public void setPassword(String JavaDoc password) {
226         this.password = password;
227     }
228
229     /**
230      * The login username for the <code>JMX</code> MBeanServer.
231      */

232     public String JavaDoc getUsername() {
233         return (this.username);
234     }
235
236     public void setUsername(String JavaDoc username) {
237         this.username = username;
238     }
239
240     /**
241      * The URL of the <code>JMX JSR 160</code> MBeanServer to be used.
242      */

243
244     public String JavaDoc getUrl() {
245         return (this.url);
246     }
247
248     public void setUrl(String JavaDoc url) {
249         this.url = url;
250     }
251
252     /**
253      * The Host of the <code>JMX JSR 160</code> MBeanServer to be used.
254      */

255
256     public String JavaDoc getHost() {
257         return (this.host);
258     }
259
260     public void setHost(String JavaDoc host) {
261         this.host = host;
262     }
263
264     /**
265      * The Port of the <code>JMX JSR 160</code> MBeanServer to be used.
266      */

267
268     public String JavaDoc getPort() {
269         return (this.port);
270     }
271
272     public void setPort(String JavaDoc port) {
273         this.port = port;
274     }
275
276     /**
277      * @return Returns the useRef.
278      */

279     public boolean isUseRef() {
280         return ref != null && !"".equals(ref);
281     }
282
283     /**
284      * @return Returns the ref.
285      */

286     public String JavaDoc getRef() {
287         return ref;
288     }
289
290     /**
291      * @param refId The ref to set.
292      */

293     public void setRef(String JavaDoc refId) {
294         this.ref = refId;
295     }
296
297     /**
298      * @return Returns the ifCondition.
299      */

300     public String JavaDoc getIf() {
301         return ifCondition;
302     }
303
304     /**
305      * Only execute if a property of the given name exists in the current
306      * project.
307      *
308      * @param c property name
309      */

310     public void setIf(String JavaDoc c) {
311         ifCondition = c;
312     }
313
314     /**
315      * @return Returns the unlessCondition.
316      */

317     public String JavaDoc getUnless() {
318         return unlessCondition;
319     }
320
321     /**
322      * Only execute if a property of the given name does not exist in the
323      * current project.
324      *
325      * @param c property name
326      */

327     public void setUnless(String JavaDoc c) {
328         unlessCondition = c;
329     }
330
331     // --------------------------------------------------------- Public Methods
332

333     /**
334      * Execute the specified command. This logic only performs the common
335      * attribute validation required by all subclasses; it does not perform any
336      * functional logic directly.
337      *
338      * @exception BuildException
339      * if a validation error occurs
340      */

341     public void execute() throws BuildException {
342         if (testIfCondition() && testUnlessCondition()) {
343             try {
344                 String JavaDoc error = null;
345
346                 MBeanServerConnection JavaDoc jmxServerConnection = getJMXConnection();
347                 error = jmxExecute(jmxServerConnection);
348                 if (error != null && isFailOnError()) {
349                     // exception should be thrown only if failOnError == true
350
// or error line will be logged twice
351
throw new BuildException(error);
352                 }
353             } catch (Throwable JavaDoc t) {
354                 if (isFailOnError()) {
355                     throw new BuildException(t);
356                 } else {
357                     handleErrorOutput(t.getMessage());
358                 }
359             } finally {
360                 closeRedirector();
361             }
362         }
363     }
364
365     /**
366      * create a new JMX Connection with auth when username and password is set.
367      */

368     public static MBeanServerConnection JavaDoc createJMXConnection(String JavaDoc url,
369             String JavaDoc host, String JavaDoc port, String JavaDoc username, String JavaDoc password)
370             throws MalformedURLException JavaDoc, IOException JavaDoc {
371         String JavaDoc urlForJMX;
372         if (url != null)
373             urlForJMX = url;
374         else
375             urlForJMX = JMX_SERVICE_PREFIX + host + ":" + port
376                     + JMX_SERVICE_SUFFIX;
377         Map JavaDoc environment = null;
378         if (username != null && password != null) {
379             String JavaDoc[] credentials = new String JavaDoc[2];
380             credentials[0] = username;
381             credentials[1] = password;
382             environment = new HashMap JavaDoc();
383             environment.put(JMXConnector.CREDENTIALS, credentials);
384         }
385         return JMXConnectorFactory.connect(new JMXServiceURL JavaDoc(urlForJMX),
386                 environment).getMBeanServerConnection();
387
388     }
389
390     /**
391      * test the if condition
392      *
393      * @return true if there is no if condition, or the named property exists
394      */

395     protected boolean testIfCondition() {
396         if (ifCondition == null || "".equals(ifCondition)) {
397             return true;
398         }
399         return getProperty(ifCondition) != null;
400     }
401
402     /**
403      * test the unless condition
404      *
405      * @return true if there is no unless condition, or there is a named
406      * property but it doesn't exist
407      */

408     protected boolean testUnlessCondition() {
409         if (unlessCondition == null || "".equals(unlessCondition)) {
410             return true;
411         }
412         return getProperty(unlessCondition) == null;
413     }
414
415     /**
416      * Get Current Connection from <em>ref</em> parameter or create a new one!
417      *
418      * @return The server connection
419      * @throws MalformedURLException
420      * @throws IOException
421      */

422     public static MBeanServerConnection JavaDoc accessJMXConnection(Project project,
423             String JavaDoc url, String JavaDoc host, String JavaDoc port, String JavaDoc username,
424             String JavaDoc password, String JavaDoc refId) throws MalformedURLException JavaDoc,
425             IOException JavaDoc {
426         MBeanServerConnection JavaDoc jmxServerConnection = null;
427         boolean isRef = project != null && refId != null && refId.length() > 0;
428         if (isRef) {
429             Object JavaDoc pref = project.getReference(refId);
430             try {
431                 jmxServerConnection = (MBeanServerConnection JavaDoc) pref;
432             } catch (ClassCastException JavaDoc cce) {
433                 if (project != null) {
434                     project.log("wrong object reference " + refId + " - "
435                             + pref.getClass());
436                 }
437                 return null;
438             }
439         }
440         if (jmxServerConnection == null) {
441             jmxServerConnection = createJMXConnection(url, host, port,
442                     username, password);
443         }
444         if (isRef && jmxServerConnection != null) {
445             project.addReference(refId, jmxServerConnection);
446         }
447         return jmxServerConnection;
448     }
449
450     // ------------------------------------------------------ protected Methods
451

452     /**
453      * get JMXConnection
454      *
455      * @return The connection
456      * @throws MalformedURLException
457      * @throws IOException
458      */

459     protected MBeanServerConnection JavaDoc getJMXConnection()
460             throws MalformedURLException JavaDoc, IOException JavaDoc {
461
462         MBeanServerConnection JavaDoc jmxServerConnection = null;
463         if (isUseRef()) {
464             Object JavaDoc pref = null ;
465             if(getProject() != null) {
466                 pref = getProject().getReference(getRef());
467                 if (pref != null) {
468                     try {
469                         jmxServerConnection = (MBeanServerConnection JavaDoc) pref;
470                     } catch (ClassCastException JavaDoc cce) {
471                         getProject().log(
472                             "Wrong object reference " + getRef() + " - "
473                                     + pref.getClass());
474                         return null;
475                     }
476                 }
477             }
478             if (jmxServerConnection == null) {
479                 jmxServerConnection = accessJMXConnection(getProject(),
480                         getUrl(), getHost(), getPort(), getUsername(),
481                         getPassword(), getRef());
482             }
483         } else {
484             jmxServerConnection = accessJMXConnection(getProject(), getUrl(),
485                     getHost(), getPort(), getUsername(), getPassword(), null);
486         }
487         return jmxServerConnection;
488     }
489
490     /**
491      * Execute the specified command, based on the configured properties. The
492      * input stream will be closed upon completion of this task, whether it was
493      * executed successfully or not.
494      *
495      * @exception Exception
496      * if an error occurs
497      */

498     public String JavaDoc jmxExecute(MBeanServerConnection JavaDoc jmxServerConnection)
499             throws Exception JavaDoc {
500
501         if ((jmxServerConnection == null)) {
502             throw new BuildException("Must open a connection!");
503         } else if (isEcho()) {
504             handleOutput("JMX Connection ref=" + ref + " is open!");
505         }
506         return null;
507     }
508
509     /**
510      * Convert string to datatype FIXME How we can transfer values from ant
511      * project reference store (ref)?
512      *
513      * @param value The value
514      * @param valueType The type
515      * @return The converted object
516      */

517     protected Object JavaDoc convertStringToType(String JavaDoc value, String JavaDoc valueType) {
518         if ("java.lang.String".equals(valueType))
519             return value;
520
521         Object JavaDoc convertValue = value;
522         if ("java.lang.Integer".equals(valueType) || "int".equals(valueType)) {
523             try {
524                 convertValue = new Integer JavaDoc(value);
525             } catch (NumberFormatException JavaDoc ex) {
526                 if (isEcho())
527                     handleErrorOutput("Unable to convert to integer:" + value);
528             }
529         } else if ("java.lang.Long".equals(valueType)
530                 || "long".equals(valueType)) {
531             try {
532                 convertValue = new Long JavaDoc(value);
533             } catch (NumberFormatException JavaDoc ex) {
534                 if (isEcho())
535                     handleErrorOutput("Unable to convert to long:" + value);
536             }
537         } else if ("java.lang.Boolean".equals(valueType)
538                 || "boolean".equals(valueType)) {
539             convertValue = new Boolean JavaDoc(value);
540         } else if ("java.lang.Float".equals(valueType)
541                 || "float".equals(valueType)) {
542             try {
543                 convertValue = new Float JavaDoc(value);
544             } catch (NumberFormatException JavaDoc ex) {
545                 if (isEcho())
546                     handleErrorOutput("Unable to convert to float:" + value);
547             }
548         } else if ("java.lang.Double".equals(valueType)
549                 || "double".equals(valueType)) {
550             try {
551                 convertValue = new Double JavaDoc(value);
552             } catch (NumberFormatException JavaDoc ex) {
553                 if (isEcho())
554                     handleErrorOutput("Unable to convert to double:" + value);
555             }
556         } else if ("javax.management.ObjectName".equals(valueType)
557                 || "name".equals(valueType)) {
558             try {
559                 convertValue = new ObjectName JavaDoc(value);
560             } catch (MalformedObjectNameException JavaDoc e) {
561                 if (isEcho())
562                     handleErrorOutput("Unable to convert to ObjectName:"
563                             + value);
564             }
565         } else if ("java.net.InetAddress".equals(valueType)) {
566             try {
567                 convertValue = InetAddress.getByName(value);
568             } catch (UnknownHostException JavaDoc exc) {
569                 if (isEcho())
570                     handleErrorOutput("Unable to resolve host name:" + value);
571             }
572         }
573         return convertValue;
574     }
575
576     /**
577      * @param name context of result
578      * @param result
579      */

580     protected void echoResult(String JavaDoc name, Object JavaDoc result) {
581         if (isEcho()) {
582             if (result.getClass().isArray()) {
583                 for (int i = 0; i < Array.getLength(result); i++) {
584                     handleOutput(name + "." + i + "=" + Array.get(result, i));
585                 }
586             } else
587                 handleOutput(name + "=" + result);
588         }
589     }
590
591     /**
592      * create result as property with name from attribute resultproperty
593      *
594      * @param result The result
595      * @see #createProperty(String, Object)
596      */

597     protected void createProperty(Object JavaDoc result) {
598         if (resultproperty != null) {
599             createProperty(resultproperty, result);
600         }
601     }
602
603     /**
604      * create result as property with name from property prefix When result is
605      * an array and isSeparateArrayResults is true, resultproperty used as
606      * prefix (<code>resultproperty.0-array.length</code> and store the
607      * result array length at <code>resultproperty.length</code>. Other
608      * option is that you delemit your result with a delimiter
609      * (java.util.StringTokenizer is used).
610      *
611      * @param propertyPrefix
612      * @param result
613      */

614     protected void createProperty(String JavaDoc propertyPrefix, Object JavaDoc result) {
615         if (propertyPrefix == null)
616             propertyPrefix = "";
617         if (result instanceof CompositeDataSupport JavaDoc) {
618             CompositeDataSupport JavaDoc data = (CompositeDataSupport JavaDoc) result;
619             CompositeType JavaDoc compositeType = data.getCompositeType();
620             Set JavaDoc keys = compositeType.keySet();
621             for (Iterator JavaDoc iter = keys.iterator(); iter.hasNext();) {
622                 String JavaDoc key = (String JavaDoc) iter.next();
623                 Object JavaDoc value = data.get(key);
624                 OpenType JavaDoc type = compositeType.getType(key);
625                 if (type instanceof SimpleType JavaDoc) {
626                     setProperty(propertyPrefix + "." + key, value);
627                 } else {
628                     createProperty(propertyPrefix + "." + key, value);
629                 }
630             }
631         } else if (result instanceof TabularDataSupport JavaDoc) {
632             TabularDataSupport JavaDoc data = (TabularDataSupport JavaDoc) result;
633             for (Iterator JavaDoc iter = data.keySet().iterator(); iter.hasNext();) {
634                 Object JavaDoc key = iter.next();
635                 for (Iterator JavaDoc iter1 = ((List JavaDoc) key).iterator(); iter1.hasNext();) {
636                     Object JavaDoc key1 = iter1.next();
637                     CompositeData JavaDoc valuedata = data.get(new Object JavaDoc[] { key1 });
638                     Object JavaDoc value = valuedata.get("value");
639                     OpenType JavaDoc type = valuedata.getCompositeType().getType(
640                             "value");
641                     if (type instanceof SimpleType JavaDoc) {
642                         setProperty(propertyPrefix + "." + key1, value);
643                     } else {
644                         createProperty(propertyPrefix + "." + key1, value);
645                     }
646                 }
647             }
648         } else if (result.getClass().isArray()) {
649             if (isSeparatearrayresults()) {
650                 int size = 0;
651                 for (int i = 0; i < Array.getLength(result); i++) {
652                     if (setProperty(propertyPrefix + "." + size, Array.get(
653                             result, i))) {
654                         size++;
655                     }
656                 }
657                 if (size > 0) {
658                     setProperty(propertyPrefix + ".Length", Integer
659                             .toString(size));
660                 }
661             }
662         } else {
663             String JavaDoc delim = getDelimiter();
664             if (delim != null) {
665                 StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(result
666                         .toString(), delim);
667                 int size = 0;
668                 for (; tokenizer.hasMoreTokens();) {
669                     String JavaDoc token = tokenizer.nextToken();
670                     if (setProperty(propertyPrefix + "." + size, token)) {
671                         size++;
672                     }
673                 }
674                 if (size > 0)
675                     setProperty(propertyPrefix + ".Length", Integer
676                             .toString(size));
677             } else {
678                 setProperty(propertyPrefix, result.toString());
679             }
680         }
681     }
682
683     /**
684      * get all properties, when project is there got all project Properties
685      * @return properties
686      */

687     public Map JavaDoc getProperties() {
688         Project currentProject = getProject();
689         if (currentProject != null) {
690             return currentProject.getProperties();
691         } else {
692             return properties;
693         }
694     }
695     
696     /**
697      * get all Properties
698      * @param property
699      * @return The property
700      */

701     public String JavaDoc getProperty(String JavaDoc property) {
702         Project currentProject = getProject();
703         if (currentProject != null) {
704             return currentProject.getProperty(property);
705         } else {
706             return properties.getProperty(property);
707         }
708     }
709
710     /**
711      * @param property The property
712      * @param value The value
713      * @return True if successful
714      */

715     public boolean setProperty(String JavaDoc property, Object JavaDoc value) {
716         if (property != null) {
717             if (value == null)
718                 value = "";
719             if (isEcho()) {
720                 handleOutput(property + "=" + value.toString());
721             }
722             Project currentProject = getProject();
723             if (currentProject != null) {
724                 currentProject.setNewProperty(property, value.toString());
725             } else {
726                 properties.setProperty(property, value.toString());
727             }
728             return true;
729         }
730         return false;
731     }
732 }
733
Popular Tags