/* * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Oracle nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This source code is provided to illustrate the usage of a given feature * or technique and has been deliberately simplified. Additional steps * required for a production-quality application, such as security checks, * input validation and proper error handling, might not be present in * this sample code. */ /* * This is a collection of utilities for Monitoring * and management API. * * File dependency: * conc.js -> for concurrency utilities */ // At any time, we maintain atmost one MBeanServer // connection. And so, we store the same as a global // variable. var mmConnection = null; function jmxConnect(hostport) { if (mmConnection != null) { // close the existing connection try { mmConnection.close(); } catch (e) { } } var JMXServiceURL = javax.management.remote.JMXServiceURL; var JMXConnectorFactory = javax.management.remote.JMXConnectorFactory; var urlPath = "/jndi/rmi://" + hostport + "/jmxrmi"; var url = new JMXServiceURL("rmi", "", 0, urlPath); var jmxc = JMXConnectorFactory.connect(url); // note that the "mmConnection" is a global variable! mmConnection = jmxc.getMBeanServerConnection(); } jmxConnect.docString = "connects to the given host, port (specified as name:port)"; function mbeanConnection() { if (mmConnection == null) { throw "Not connected to MBeanServer yet!"; } return mmConnection; } mbeanConnection.docString = "returns the current MBeanServer connection"; /** * Returns a platform MXBean proxy for given MXBean name and interface class */ function newPlatformMXBeanProxy(name, intf) { var factory = java.lang.management.ManagementFactory; return factory.newPlatformMXBeanProxy(mbeanConnection(), name, intf); } newPlatformMXBeanProxy.docString = "returns a proxy for a platform MXBean"; /** * Wraps a string to ObjectName if needed. */ function objectName(objName) { var ObjectName = Packages.javax.management.ObjectName; if (objName instanceof ObjectName) { return objName; } else { return new ObjectName(objName); } } objectName.docString = "creates JMX ObjectName for a given String"; /** * Creates a new (M&M) Attribute object * * @param name name of the attribute * @param value value of the attribute */ function attribute(name, value) { var Attribute = Packages.javax.management.Attribute; return new Attribute(name, value); } attribute.docString = "returns a new JMX Attribute using name and value given"; /** * Returns MBeanInfo for given ObjectName. Strings are accepted. */ function mbeanInfo(objName) { objName = objectName(objName); return mbeanConnection().getMBeanInfo(objName); } mbeanInfo.docString = "returns MBeanInfo of a given ObjectName"; /** * Returns ObjectInstance for a given ObjectName. */ function objectInstance(objName) { objName = objectName(objName); return mbeanConnection().objectInstance(objectName); } objectInstance.docString = "returns ObjectInstance for a given ObjectName"; /** * Queries with given ObjectName and QueryExp. * QueryExp may be null. * * @return set of ObjectNames. */ function queryNames(objName, query) { objName = objectName(objName); if (query == undefined) query = null; return mbeanConnection().queryNames(objName, query); } queryNames.docString = "returns QueryNames using given ObjectName and optional query"; /** * Queries with given ObjectName and QueryExp. * QueryExp may be null. * * @return set of ObjectInstances. */ function queryMBeans(objName, query) { objName = objectName(objName); if (query == undefined) query = null; return mbeanConnection().queryMBeans(objName, query); } queryMBeans.docString = "return MBeans using given ObjectName and optional query"; // wraps a script array as java.lang.Object[] function objectArray(array) { return Java.to(array, "java.lang.Object[]"); } // wraps a script (string) array as java.lang.String[] function stringArray(array) { return Java.to(array, "java.lang.String[]"); } // script array to Java List function toAttrList(array) { var AttributeList = Packages.javax.management.AttributeList; if (array instanceof AttributeList) { return array; } var list = new AttributeList(array.length); for (var index = 0; index < array.length; index++) { list.add(array[index]); } return list; } // Java Collection (Iterable) to script array function toArray(collection) { if (collection instanceof Array) { return collection; } var itr = collection.iterator(); var array = new Array(); while (itr.hasNext()) { array[array.length] = itr.next(); } return array; } // gets MBean attributes function getMBeanAttributes(objName, attributeNames) { objName = objectName(objName); return mbeanConnection().getAttributes(objName,stringArray(attributeNames)); } getMBeanAttributes.docString = "returns specified Attributes of given ObjectName"; // gets MBean attribute function getMBeanAttribute(objName, attrName) { objName = objectName(objName); return mbeanConnection().getAttribute(objName, attrName); } getMBeanAttribute.docString = "returns a single Attribute of given ObjectName"; // sets MBean attributes function setMBeanAttributes(objName, attrList) { objName = objectName(objName); attrList = toAttrList(attrList); return mbeanConnection().setAttributes(objName, attrList); } setMBeanAttributes.docString = "sets specified Attributes of given ObjectName"; // sets MBean attribute function setMBeanAttribute(objName, attrName, attrValue) { var Attribute = Packages.javax.management.Attribute; objName = objectName(objName); mbeanConnection().setAttribute(objName, new Attribute(attrName, attrValue)); } setMBeanAttribute.docString = "sets a single Attribute of given ObjectName"; // invokes an operation on given MBean function invokeMBean(objName, operation, params, signature) { objName = objectName(objName); params = objectArray(params); signature = stringArray(signature); return mbeanConnection().invoke(objName, operation, params, signature); } invokeMBean.docString = "invokes MBean operation on given ObjectName"; /** * Wraps a MBean specified by ObjectName as a convenient * script object -- so that setting/getting MBean attributes * and invoking MBean method can be done with natural syntax. * * @param objName ObjectName of the MBean * @param async asynchornous mode [optional, default is false] * @return script wrapper for MBean * * With async mode, all field, operation access is async. Results * will be of type FutureTask. When you need value, call 'get' on it. */ function mbean(objName, async) { var index; objName = objectName(objName); var info = mbeanInfo(objName); var attrs = info.attributes; var attrMap = new Object; for (index in attrs) { attrMap[attrs[index].name] = attrs[index]; } var opers = info.operations; var operMap = new Object; for (index in opers) { operMap[opers[index].name] = opers[index]; } function isAttribute(name) { return name in attrMap; } function isOperation(name) { return name in operMap; } return new JSAdapter() { __has__: function (name) { return isAttribute(name) || isOperation(name); }, __get__: function (name) { if (isAttribute(name)) { if (async) { return getMBeanAttribute.future(objName, name); } else { return getMBeanAttribute(objName, name); } } else { return undefined; } }, __call__: function(name) { if (isOperation(name)) { var oper = operMap[name]; var params = []; for (var j = 1; j < arguments.length; j++) { params[j-1]= arguments[j]; } var sigs = oper.signature; var sigNames = new Array(sigs.length); for (var index in sigs) { sigNames[index] = sigs[index].getType(); } if (async) { return invokeMBean.future(objName, name, params, sigNames); } else { return invokeMBean(objName, name, params, sigNames); } } else { return undefined; } }, __put__: function (name, value) { if (isAttribute(name)) { if (async) { setMBeanAttribute.future(objName, name, value); } else { setMBeanAttribute(objName, name, value); } } else { return undefined; } } }; } mbean.docString = "returns a conveninent script wrapper for a MBean of given ObjectName"; if (this.application != undefined) { this.application.addTool("JMX Connect", // connect to a JMX MBean Server function () { var url = prompt("Connect to JMX server (host:port)"); if (url != null) { try { jmxConnect(url); alert("connected!"); } catch (e) { error(e, "Can not connect to " + url); } } }); }