/projects/tomcat-7.0.2/java/org/apache/catalina/ant/jmx/JMXAccessorTask.java
Java | 731 lines | 420 code | 81 blank | 230 comment | 115 complexity | ac2f88f6a158b28d6775c4468ed99002 MD5 | raw file
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.catalina.ant.jmx;
- import java.io.IOException;
- import java.lang.reflect.Array;
- import java.net.InetAddress;
- import java.net.MalformedURLException;
- import java.net.UnknownHostException;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.Properties;
- import java.util.Set;
- import java.util.StringTokenizer;
- import javax.management.MBeanServerConnection;
- import javax.management.MalformedObjectNameException;
- import javax.management.ObjectName;
- import javax.management.openmbean.CompositeData;
- import javax.management.openmbean.CompositeDataSupport;
- import javax.management.openmbean.CompositeType;
- import javax.management.openmbean.OpenType;
- import javax.management.openmbean.SimpleType;
- import javax.management.openmbean.TabularDataSupport;
- import javax.management.remote.JMXConnector;
- import javax.management.remote.JMXConnectorFactory;
- import javax.management.remote.JMXServiceURL;
- import org.apache.catalina.ant.BaseRedirectorHelperTask;
- import org.apache.tools.ant.BuildException;
- import org.apache.tools.ant.Project;
- /**
- * Access <em>JMX</em> JSR 160 MBeans Server.
- * <ul>
- * <li>open more then one JSR 160 rmi connection</li>
- * <li>Get/Set Mbeans attributes</li>
- * <li>Call Mbean Operation with arguments</li>
- * <li>Argument values can be converted from string to
- * int,long,float,double,boolean,ObjectName or InetAddress</li>
- * <li>Query Mbeans</li>
- * <li>Show Get, Call, Query result at Ant console log</li>
- * <li>Bind Get, Call, Query result at Ant properties</li>
- * </ul>
- *
- * Examples: open server with reference and autorisation
- *
- * <pre>
- *
- * <jmxOpen
- * host="127.0.0.1"
- * port="9014"
- * username="monitorRole"
- * password="mysecret"
- * ref="jmx.myserver"
- * />
- *
- * </pre>
- *
- * All calls after opening with same refid reuse the connection.
- * <p>
- * First call to a remote MBeanserver save the JMXConnection a referenz
- * <em>jmx.server</em>
- * </p>
- * All JMXAccessorXXXTask support the attribute <em>if</em> and
- * <em>unless</em>. With <em>if</em> the task is only execute when property
- * exist and with <em>unless</em> when property not exists. <br/><b>NOTE
- * </b>: These tasks require Ant 1.6 or later interface.
- *
- * @author Peter Rossbach
- * @version $Id: JMXAccessorTask.java 939305 2010-04-29 13:43:39Z kkolinko $
- * @since 5.5.10
- */
- public class JMXAccessorTask extends BaseRedirectorHelperTask {
- public static final String JMX_SERVICE_PREFIX = "service:jmx:rmi:///jndi/rmi://";
- public static final String JMX_SERVICE_SUFFIX = "/jmxrmi";
- // ----------------------------------------------------- Instance Variables
- private String name = null;
- private String resultproperty;
- private String url = null;
- private String host = "localhost";
- private String port = "8050";
- private String password = null;
- private String username = null;
- private String ref = "jmx.server";
- private boolean echo = false;
- private boolean separatearrayresults = true;
- private String delimiter;
- private String unlessCondition;
- private String ifCondition;
- private Properties properties = new Properties();
- // ----------------------------------------------------- Instance Info
- /**
- * Descriptive information describing this implementation.
- */
- private static final String info = "org.apache.catalina.ant.JMXAccessorTask/1.1";
- /**
- * Return descriptive information about this implementation and the
- * corresponding version number, in the format
- * <code><description>/<version></code>.
- */
- public String getInfo() {
- return (info);
- }
- // ------------------------------------------------------------- Properties
- /**
- * The name used at remote MbeanServer
- */
- public String getName() {
- return (this.name);
- }
- public void setName(String objectName) {
- this.name = objectName;
- }
- /**
- * @return Returns the resultproperty.
- */
- public String getResultproperty() {
- return resultproperty;
- }
- /**
- * @param propertyName The resultproperty to set.
- */
- public void setResultproperty(String propertyName) {
- this.resultproperty = propertyName;
- }
- /**
- * @return Returns the delimiter.
- */
- public String getDelimiter() {
- return delimiter;
- }
- /**
- * @param separator The delimiter to set.
- */
- public void setDelimiter(String separator) {
- this.delimiter = separator;
- }
- /**
- * @return Returns the echo.
- */
- public boolean isEcho() {
- return echo;
- }
- /**
- * @param echo
- * The echo to set.
- */
- public void setEcho(boolean echo) {
- this.echo = echo;
- }
- /**
- * @return Returns the separatearrayresults.
- */
- public boolean isSeparatearrayresults() {
- return separatearrayresults;
- }
- /**
- * @param separateArrayResults
- * The separatearrayresults to set.
- */
- public void setSeparatearrayresults(boolean separateArrayResults) {
- this.separatearrayresults = separateArrayResults;
- }
- /**
- * The login password for the <code>Manager</code> application.
- */
- public String getPassword() {
- return (this.password);
- }
- public void setPassword(String password) {
- this.password = password;
- }
- /**
- * The login username for the <code>JMX</code> MBeanServer.
- */
- public String getUsername() {
- return (this.username);
- }
- public void setUsername(String username) {
- this.username = username;
- }
- /**
- * The URL of the <code>JMX JSR 160</code> MBeanServer to be used.
- */
- public String getUrl() {
- return (this.url);
- }
- public void setUrl(String url) {
- this.url = url;
- }
- /**
- * The Host of the <code>JMX JSR 160</code> MBeanServer to be used.
- */
- public String getHost() {
- return (this.host);
- }
- public void setHost(String host) {
- this.host = host;
- }
- /**
- * The Port of the <code>JMX JSR 160</code> MBeanServer to be used.
- */
- public String getPort() {
- return (this.port);
- }
- public void setPort(String port) {
- this.port = port;
- }
- /**
- * @return Returns the useRef.
- */
- public boolean isUseRef() {
- return ref != null && !"".equals(ref);
- }
- /**
- * @return Returns the ref.
- */
- public String getRef() {
- return ref;
- }
- /**
- * @param refId The ref to set.
- */
- public void setRef(String refId) {
- this.ref = refId;
- }
- /**
- * @return Returns the ifCondition.
- */
- public String getIf() {
- return ifCondition;
- }
- /**
- * Only execute if a property of the given name exists in the current
- * project.
- *
- * @param c property name
- */
- public void setIf(String c) {
- ifCondition = c;
- }
- /**
- * @return Returns the unlessCondition.
- */
- public String getUnless() {
- return unlessCondition;
- }
- /**
- * Only execute if a property of the given name does not exist in the
- * current project.
- *
- * @param c property name
- */
- public void setUnless(String c) {
- unlessCondition = c;
- }
- // --------------------------------------------------------- Public Methods
- /**
- * Execute the specified command. This logic only performs the common
- * attribute validation required by all subclasses; it does not perform any
- * functional logic directly.
- *
- * @exception BuildException
- * if a validation error occurs
- */
- @Override
- public void execute() throws BuildException {
- if (testIfCondition() && testUnlessCondition()) {
- try {
- String error = null;
- MBeanServerConnection jmxServerConnection = getJMXConnection();
- error = jmxExecute(jmxServerConnection);
- if (error != null && isFailOnError()) {
- // exception should be thrown only if failOnError == true
- // or error line will be logged twice
- throw new BuildException(error);
- }
- } catch (Throwable t) {
- if (isFailOnError()) {
- throw new BuildException(t);
- } else {
- handleErrorOutput(t.getMessage());
- }
- } finally {
- closeRedirector();
- }
- }
- }
- /**
- * create a new JMX Connection with auth when username and password is set.
- */
- public static MBeanServerConnection createJMXConnection(String url,
- String host, String port, String username, String password)
- throws MalformedURLException, IOException {
- String urlForJMX;
- if (url != null)
- urlForJMX = url;
- else
- urlForJMX = JMX_SERVICE_PREFIX + host + ":" + port
- + JMX_SERVICE_SUFFIX;
- Map<String, String[]> environment = null;
- if (username != null && password != null) {
- String[] credentials = new String[2];
- credentials[0] = username;
- credentials[1] = password;
- environment = new HashMap<String, String[]>();
- environment.put(JMXConnector.CREDENTIALS, credentials);
- }
- return JMXConnectorFactory.connect(new JMXServiceURL(urlForJMX),
- environment).getMBeanServerConnection();
- }
- /**
- * test the if condition
- *
- * @return true if there is no if condition, or the named property exists
- */
- protected boolean testIfCondition() {
- if (ifCondition == null || "".equals(ifCondition)) {
- return true;
- }
- return getProperty(ifCondition) != null;
- }
- /**
- * test the unless condition
- *
- * @return true if there is no unless condition, or there is a named
- * property but it doesn't exist
- */
- protected boolean testUnlessCondition() {
- if (unlessCondition == null || "".equals(unlessCondition)) {
- return true;
- }
- return getProperty(unlessCondition) == null;
- }
- /**
- * Get Current Connection from <em>ref</em> parameter or create a new one!
- *
- * @return The server connection
- * @throws MalformedURLException
- * @throws IOException
- */
- public static MBeanServerConnection accessJMXConnection(Project project,
- String url, String host, String port, String username,
- String password, String refId) throws MalformedURLException,
- IOException {
- MBeanServerConnection jmxServerConnection = null;
- boolean isRef = project != null && refId != null && refId.length() > 0;
- if (isRef) {
- Object pref = project.getReference(refId);
- try {
- jmxServerConnection = (MBeanServerConnection) pref;
- } catch (ClassCastException cce) {
- project.log("wrong object reference " + refId + " - "
- + pref.getClass());
- return null;
- }
- }
- if (jmxServerConnection == null) {
- jmxServerConnection = createJMXConnection(url, host, port,
- username, password);
- }
- if (isRef && jmxServerConnection != null) {
- project.addReference(refId, jmxServerConnection);
- }
- return jmxServerConnection;
- }
- // ------------------------------------------------------ protected Methods
- /**
- * get JMXConnection
- *
- * @return The connection
- * @throws MalformedURLException
- * @throws IOException
- */
- protected MBeanServerConnection getJMXConnection()
- throws MalformedURLException, IOException {
- MBeanServerConnection jmxServerConnection = null;
- if (isUseRef()) {
- Object pref = null ;
- if(getProject() != null) {
- pref = getProject().getReference(getRef());
- if (pref != null) {
- try {
- jmxServerConnection = (MBeanServerConnection) pref;
- } catch (ClassCastException cce) {
- getProject().log(
- "Wrong object reference " + getRef() + " - "
- + pref.getClass());
- return null;
- }
- }
- }
- if (jmxServerConnection == null) {
- jmxServerConnection = accessJMXConnection(getProject(),
- getUrl(), getHost(), getPort(), getUsername(),
- getPassword(), getRef());
- }
- } else {
- jmxServerConnection = accessJMXConnection(getProject(), getUrl(),
- getHost(), getPort(), getUsername(), getPassword(), null);
- }
- return jmxServerConnection;
- }
- /**
- * Execute the specified command, based on the configured properties. The
- * input stream will be closed upon completion of this task, whether it was
- * executed successfully or not.
- *
- * @exception Exception
- * if an error occurs
- */
- public String jmxExecute(MBeanServerConnection jmxServerConnection)
- throws Exception {
- if ((jmxServerConnection == null)) {
- throw new BuildException("Must open a connection!");
- } else if (isEcho()) {
- handleOutput("JMX Connection ref=" + ref + " is open!");
- }
- return null;
- }
- /**
- * Convert string to datatype FIXME How we can transfer values from ant
- * project reference store (ref)?
- *
- * @param value The value
- * @param valueType The type
- * @return The converted object
- */
- protected Object convertStringToType(String value, String valueType) {
- if ("java.lang.String".equals(valueType))
- return value;
- Object convertValue = value;
- if ("java.lang.Integer".equals(valueType) || "int".equals(valueType)) {
- try {
- convertValue = new Integer(value);
- } catch (NumberFormatException ex) {
- if (isEcho())
- handleErrorOutput("Unable to convert to integer:" + value);
- }
- } else if ("java.lang.Long".equals(valueType)
- || "long".equals(valueType)) {
- try {
- convertValue = new Long(value);
- } catch (NumberFormatException ex) {
- if (isEcho())
- handleErrorOutput("Unable to convert to long:" + value);
- }
- } else if ("java.lang.Boolean".equals(valueType)
- || "boolean".equals(valueType)) {
- convertValue = new Boolean(value);
- } else if ("java.lang.Float".equals(valueType)
- || "float".equals(valueType)) {
- try {
- convertValue = new Float(value);
- } catch (NumberFormatException ex) {
- if (isEcho())
- handleErrorOutput("Unable to convert to float:" + value);
- }
- } else if ("java.lang.Double".equals(valueType)
- || "double".equals(valueType)) {
- try {
- convertValue = new Double(value);
- } catch (NumberFormatException ex) {
- if (isEcho())
- handleErrorOutput("Unable to convert to double:" + value);
- }
- } else if ("javax.management.ObjectName".equals(valueType)
- || "name".equals(valueType)) {
- try {
- convertValue = new ObjectName(value);
- } catch (MalformedObjectNameException e) {
- if (isEcho())
- handleErrorOutput("Unable to convert to ObjectName:"
- + value);
- }
- } else if ("java.net.InetAddress".equals(valueType)) {
- try {
- convertValue = InetAddress.getByName(value);
- } catch (UnknownHostException exc) {
- if (isEcho())
- handleErrorOutput("Unable to resolve host name:" + value);
- }
- }
- return convertValue;
- }
- /**
- * @param name context of result
- * @param result
- */
- protected void echoResult(String name, Object result) {
- if (isEcho()) {
- if (result.getClass().isArray()) {
- for (int i = 0; i < Array.getLength(result); i++) {
- handleOutput(name + "." + i + "=" + Array.get(result, i));
- }
- } else
- handleOutput(name + "=" + result);
- }
- }
- /**
- * create result as property with name from attribute resultproperty
- *
- * @param result The result
- * @see #createProperty(String, Object)
- */
- protected void createProperty(Object result) {
- if (resultproperty != null) {
- createProperty(resultproperty, result);
- }
- }
- /**
- * create result as property with name from property prefix When result is
- * an array and isSeparateArrayResults is true, resultproperty used as
- * prefix (<code>resultproperty.0-array.length</code> and store the
- * result array length at <code>resultproperty.length</code>. Other
- * option is that you delimit your result with a delimiter
- * (java.util.StringTokenizer is used).
- *
- * @param propertyPrefix
- * @param result
- */
- protected void createProperty(String propertyPrefix, Object result) {
- if (propertyPrefix == null)
- propertyPrefix = "";
- if (result instanceof CompositeDataSupport) {
- CompositeDataSupport data = (CompositeDataSupport) result;
- CompositeType compositeType = data.getCompositeType();
- Set<String> keys = compositeType.keySet();
- for (Iterator<String> iter = keys.iterator(); iter.hasNext();) {
- String key = iter.next();
- Object value = data.get(key);
- OpenType<?> type = compositeType.getType(key);
- if (type instanceof SimpleType<?>) {
- setProperty(propertyPrefix + "." + key, value);
- } else {
- createProperty(propertyPrefix + "." + key, value);
- }
- }
- } else if (result instanceof TabularDataSupport) {
- TabularDataSupport data = (TabularDataSupport) result;
- for (Iterator<Object> iter = data.keySet().iterator(); iter.hasNext();) {
- Object key = iter.next();
- for (Iterator<?> iter1 = ((List<?>) key).iterator(); iter1.hasNext();) {
- Object key1 = iter1.next();
- CompositeData valuedata = data.get(new Object[] { key1 });
- Object value = valuedata.get("value");
- OpenType<?> type = valuedata.getCompositeType().getType(
- "value");
- if (type instanceof SimpleType<?>) {
- setProperty(propertyPrefix + "." + key1, value);
- } else {
- createProperty(propertyPrefix + "." + key1, value);
- }
- }
- }
- } else if (result.getClass().isArray()) {
- if (isSeparatearrayresults()) {
- int size = 0;
- for (int i = 0; i < Array.getLength(result); i++) {
- if (setProperty(propertyPrefix + "." + size, Array.get(
- result, i))) {
- size++;
- }
- }
- if (size > 0) {
- setProperty(propertyPrefix + ".Length", Integer
- .toString(size));
- }
- }
- } else {
- String delim = getDelimiter();
- if (delim != null) {
- StringTokenizer tokenizer = new StringTokenizer(result
- .toString(), delim);
- int size = 0;
- for (; tokenizer.hasMoreTokens();) {
- String token = tokenizer.nextToken();
- if (setProperty(propertyPrefix + "." + size, token)) {
- size++;
- }
- }
- if (size > 0)
- setProperty(propertyPrefix + ".Length", Integer
- .toString(size));
- } else {
- setProperty(propertyPrefix, result.toString());
- }
- }
- }
- /**
- * get all properties, when project is there got all project Properties
- * @return properties
- */
- public Map getProperties() {
- Project currentProject = getProject();
- if (currentProject != null) {
- return currentProject.getProperties();
- } else {
- return properties;
- }
- }
-
- /**
- * get all Properties
- * @param property
- * @return The property
- */
- public String getProperty(String property) {
- Project currentProject = getProject();
- if (currentProject != null) {
- return currentProject.getProperty(property);
- } else {
- return properties.getProperty(property);
- }
- }
- /**
- * @param property The property
- * @param value The value
- * @return True if successful
- */
- public boolean setProperty(String property, Object value) {
- if (property != null) {
- if (value == null)
- value = "";
- if (isEcho()) {
- handleOutput(property + "=" + value.toString());
- }
- Project currentProject = getProject();
- if (currentProject != null) {
- currentProject.setNewProperty(property, value.toString());
- } else {
- properties.setProperty(property, value.toString());
- }
- return true;
- }
- return false;
- }
- }