1 /* 2 * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * This source code is provided to illustrate the usage of a given feature 34 * or technique and has been deliberately simplified. Additional steps 35 * required for a production-quality application, such as security checks, 36 * input validation and proper error handling, might not be present in 37 * this sample code. 38 */ 39 40 /* 41 * This is a collection of utilities for Monitoring 42 * and management API. 43 * 44 * File dependency: 45 * conc.js -> for concurrency utilities 46 */ 47 48 // At any time, we maintain atmost one MBeanServer 49 // connection. And so, we store the same as a global 50 // variable. 51 var mmConnection = null; 52 53 function jmxConnect(hostport) { 54 if (mmConnection != null) { 55 // close the existing connection 56 try { 57 mmConnection.close(); 58 } catch (e) { 59 } 60 } 61 62 var JMXServiceURL = javax.management.remote.JMXServiceURL; 63 var JMXConnectorFactory = javax.management.remote.JMXConnectorFactory; 64 65 var urlPath = "/jndi/rmi://" + hostport + "/jmxrmi"; 66 var url = new JMXServiceURL("rmi", "", 0, urlPath); 67 var jmxc = JMXConnectorFactory.connect(url); 68 // note that the "mmConnection" is a global variable! 69 mmConnection = jmxc.getMBeanServerConnection(); 70 } 71 jmxConnect.docString = "connects to the given host, port (specified as name:port)"; 72 73 function mbeanConnection() { 74 if (mmConnection == null) { 75 throw "Not connected to MBeanServer yet!"; 76 } 77 78 return mmConnection; 79 } 80 mbeanConnection.docString = "returns the current MBeanServer connection"; 81 82 /** 83 * Returns a platform MXBean proxy for given MXBean name and interface class 84 */ 85 function newPlatformMXBeanProxy(name, intf) { 86 var factory = java.lang.management.ManagementFactory; 87 return factory.newPlatformMXBeanProxy(mbeanConnection(), name, intf); 88 } 89 newPlatformMXBeanProxy.docString = "returns a proxy for a platform MXBean"; 90 91 /** 92 * Wraps a string to ObjectName if needed. 93 */ 94 function objectName(objName) { 95 var ObjectName = Packages.javax.management.ObjectName; 96 if (objName instanceof ObjectName) { 97 return objName; 98 } else { 99 return new ObjectName(objName); 100 } 101 } 102 objectName.docString = "creates JMX ObjectName for a given String"; 103 104 /** 105 * Creates a new (M&M) Attribute object 106 * 107 * @param name name of the attribute 108 * @param value value of the attribute 109 */ 110 function attribute(name, value) { 111 var Attribute = Packages.javax.management.Attribute; 112 return new Attribute(name, value); 113 } 114 attribute.docString = "returns a new JMX Attribute using name and value given"; 115 116 /** 117 * Returns MBeanInfo for given ObjectName. Strings are accepted. 118 */ 119 function mbeanInfo(objName) { 120 objName = objectName(objName); 121 return mbeanConnection().getMBeanInfo(objName); 122 } 123 mbeanInfo.docString = "returns MBeanInfo of a given ObjectName"; 124 125 /** 126 * Returns ObjectInstance for a given ObjectName. 127 */ 128 function objectInstance(objName) { 129 objName = objectName(objName); 130 return mbeanConnection().objectInstance(objectName); 131 } 132 objectInstance.docString = "returns ObjectInstance for a given ObjectName"; 133 134 /** 135 * Queries with given ObjectName and QueryExp. 136 * QueryExp may be null. 137 * 138 * @return set of ObjectNames. 139 */ 140 function queryNames(objName, query) { 141 objName = objectName(objName); 142 if (query == undefined) query = null; 143 return mbeanConnection().queryNames(objName, query); 144 } 145 queryNames.docString = "returns QueryNames using given ObjectName and optional query"; 146 147 /** 148 * Queries with given ObjectName and QueryExp. 149 * QueryExp may be null. 150 * 151 * @return set of ObjectInstances. 152 */ 153 function queryMBeans(objName, query) { 154 objName = objectName(objName); 155 if (query == undefined) query = null; 156 return mbeanConnection().queryMBeans(objName, query); 157 } 158 queryMBeans.docString = "return MBeans using given ObjectName and optional query"; 159 160 // wraps a script array as java.lang.Object[] 161 function objectArray(array) { 162 return Java.to(array, "java.lang.Object[]"); 163 } 164 165 // wraps a script (string) array as java.lang.String[] 166 function stringArray(array) { 167 return Java.to(array, "java.lang.String[]"); 168 } 169 170 // script array to Java List 171 function toAttrList(array) { 172 var AttributeList = Packages.javax.management.AttributeList; 173 if (array instanceof AttributeList) { 174 return array; 175 } 176 var list = new AttributeList(array.length); 177 for (var index = 0; index < array.length; index++) { 178 list.add(array[index]); 179 } 180 return list; 181 } 182 183 // Java Collection (Iterable) to script array 184 function toArray(collection) { 185 if (collection instanceof Array) { 186 return collection; 187 } 188 var itr = collection.iterator(); 189 var array = new Array(); 190 while (itr.hasNext()) { 191 array[array.length] = itr.next(); 192 } 193 return array; 194 } 195 196 // gets MBean attributes 197 function getMBeanAttributes(objName, attributeNames) { 198 objName = objectName(objName); 199 return mbeanConnection().getAttributes(objName,stringArray(attributeNames)); 200 } 201 getMBeanAttributes.docString = "returns specified Attributes of given ObjectName"; 202 203 // gets MBean attribute 204 function getMBeanAttribute(objName, attrName) { 205 objName = objectName(objName); 206 return mbeanConnection().getAttribute(objName, attrName); 207 } 208 getMBeanAttribute.docString = "returns a single Attribute of given ObjectName"; 209 210 // sets MBean attributes 211 function setMBeanAttributes(objName, attrList) { 212 objName = objectName(objName); 213 attrList = toAttrList(attrList); 214 return mbeanConnection().setAttributes(objName, attrList); 215 } 216 setMBeanAttributes.docString = "sets specified Attributes of given ObjectName"; 217 218 // sets MBean attribute 219 function setMBeanAttribute(objName, attrName, attrValue) { 220 var Attribute = Packages.javax.management.Attribute; 221 objName = objectName(objName); 222 mbeanConnection().setAttribute(objName, new Attribute(attrName, attrValue)); 223 } 224 setMBeanAttribute.docString = "sets a single Attribute of given ObjectName"; 225 226 // invokes an operation on given MBean 227 function invokeMBean(objName, operation, params, signature) { 228 objName = objectName(objName); 229 params = objectArray(params); 230 signature = stringArray(signature); 231 return mbeanConnection().invoke(objName, operation, params, signature); 232 } 233 invokeMBean.docString = "invokes MBean operation on given ObjectName"; 234 235 /** 236 * Wraps a MBean specified by ObjectName as a convenient 237 * script object -- so that setting/getting MBean attributes 238 * and invoking MBean method can be done with natural syntax. 239 * 240 * @param objName ObjectName of the MBean 241 * @param async asynchornous mode [optional, default is false] 242 * @return script wrapper for MBean 243 * 244 * With async mode, all field, operation access is async. Results 245 * will be of type FutureTask. When you need value, call 'get' on it. 246 */ 247 function mbean(objName, async) { 248 var index; 249 objName = objectName(objName); 250 var info = mbeanInfo(objName); 251 var attrs = info.attributes; 252 var attrMap = new Object; 253 for (index in attrs) { 254 attrMap[attrs[index].name] = attrs[index]; 255 } 256 var opers = info.operations; 257 var operMap = new Object; 258 for (index in opers) { 259 operMap[opers[index].name] = opers[index]; 260 } 261 262 function isAttribute(name) { 263 return name in attrMap; 264 } 265 266 function isOperation(name) { 267 return name in operMap; 268 } 269 270 return new JSAdapter() { 271 __has__: function (name) { 272 return isAttribute(name) || isOperation(name); 273 }, 274 __get__: function (name) { 275 if (isAttribute(name)) { 276 if (async) { 277 return getMBeanAttribute.future(objName, name); 278 } else { 279 return getMBeanAttribute(objName, name); 280 } 281 } else { 282 return undefined; 283 } 284 }, 285 __call__: function(name) { 286 if (isOperation(name)) { 287 var oper = operMap[name]; 288 289 var params = []; 290 for (var j = 1; j < arguments.length; j++) { 291 params[j-1]= arguments[j]; 292 } 293 294 var sigs = oper.signature; 295 296 var sigNames = new Array(sigs.length); 297 for (var index in sigs) { 298 sigNames[index] = sigs[index].getType(); 299 } 300 301 if (async) { 302 return invokeMBean.future(objName, name, params, sigNames); 303 } else { 304 return invokeMBean(objName, name, params, sigNames); 305 } 306 } else { 307 return undefined; 308 } 309 }, 310 __put__: function (name, value) { 311 if (isAttribute(name)) { 312 if (async) { 313 setMBeanAttribute.future(objName, name, value); 314 } else { 315 setMBeanAttribute(objName, name, value); 316 } 317 } else { 318 return undefined; 319 } 320 } 321 }; 322 } 323 mbean.docString = "returns a conveninent script wrapper for a MBean of given ObjectName"; 324 325 if (this.application != undefined) { 326 this.application.addTool("JMX Connect", 327 // connect to a JMX MBean Server 328 function () { 329 var url = prompt("Connect to JMX server (host:port)"); 330 if (url != null) { 331 try { 332 jmxConnect(url); 333 alert("connected!"); 334 } catch (e) { 335 error(e, "Can not connect to " + url); 336 } 337 } 338 }); 339 } 340