blob: 2d1883533b4f31758aa11fcc6bc07c835adbd6b3 [file] [log] [blame]
/*
*
* 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.qpid.management.ui.jmx;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.InstanceNotFoundException;
import javax.management.JMException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import org.apache.qpid.management.ui.ApplicationRegistry;
import org.apache.qpid.management.ui.ManagedBean;
import org.apache.qpid.management.ui.ManagedServer;
import org.apache.qpid.management.ui.exceptions.ManagementConsoleException;
import org.apache.qpid.management.ui.model.AttributeData;
import org.apache.qpid.management.ui.model.ManagedAttributeModel;
import org.apache.qpid.management.ui.model.NotificationInfoModel;
import org.apache.qpid.management.ui.model.OperationData;
import org.apache.qpid.management.ui.model.OperationDataModel;
import org.apache.qpid.management.ui.model.ParameterData;
import org.apache.qpid.management.ui.views.ViewUtility;
/**
* Utility class for all mbeanserver related operations. Keeps all JMX code out from view and model classes
* @author Bhupendra Bhardwaj
*/
public class MBeanUtility
{
public static final BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE);
public static final BigInteger MAX_INT = BigInteger.valueOf(Integer.MAX_VALUE);
/**
* Retrieves the MBeanInfo from MBeanServer and stores in the application registry
* @param mbean managed bean
* @return MBeanInfo
* @throws Exception, if server connection is null or if server throws Exception
*/
public static MBeanInfo getMBeanInfo(ManagedBean mbean) throws Exception
{
ManagedServer server = mbean.getServer();
JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
MBeanServerConnection mbsc = serverRegistry.getServerConnection();
if (mbsc == null)
{
throw new ManagementConsoleException("Server connection is broken");
}
JMXManagedObject jmxbean = (JMXManagedObject)mbean;
MBeanInfo mbeanInfo = mbsc.getMBeanInfo(jmxbean.getObjectName());
serverRegistry.putMBeanInfo(mbean, mbeanInfo);
// populate the server registry with attribute and operation info
getAttributes(mbean);
getOperations(mbean);
return mbeanInfo;
}
/**
* executes the MBean operation
* @param mbean
* @param opData
* @return MBean operation return value
* @throws Exception if server connection is broken or if operation execution fails on the mbean server
*/
public static Object execute(ManagedBean mbean, OperationData opData) throws Exception
{
String opName = opData.getName();
Object[] values = null;
String[] signature = null;
List<ParameterData> params = opData.getParameters();
if (params != null && !params.isEmpty())
{
signature = new String[params.size()];;
values = new Object[params.size()];
for (int i = 0; i < params.size(); i++)
{
signature[i] = params.get(i).getType();
values[i] = params.get(i).getValue();
}
}
ManagedServer server = mbean.getServer();
JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
MBeanServerConnection mbsc = serverRegistry.getServerConnection();
if (mbsc == null)
{
throw new ManagementConsoleException("Server connection is broken");
// TODO
// try and get the connection again if it was disconnected
}
JMXManagedObject jmxbean = (JMXManagedObject)mbean;
return mbsc.invoke(jmxbean.getObjectName(), opName, values, signature);
}
/**
* @see MBeanUtility#handleException(ManagedBean, Exception)
*/
public static void handleException(Exception ex)
{
handleException(null, ex);
}
/**
* handels the exception received. Shows the exception to the user in best suitable way
* @param mbean managed bean
* @param ex Exception
*/
public static void handleException(ManagedBean mbean, Throwable ex)
{
if (mbean == null)
{
ViewUtility.popupErrorMessage("Error", "Managed Object is null \n" + ex.toString());
printStackTrace(ex);
}
else if (ex instanceof ReflectionException)
{
ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Server has thrown error \n" + ex.toString());
printStackTrace(ex);
}
else if (ex instanceof InstanceNotFoundException)
{
ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Managed Object Not Found \n" + ex.toString());
printStackTrace(ex);
}
else if (ex instanceof MBeanException)
{
String cause = ((MBeanException)ex).getTargetException().getMessage();
if (cause == null)
cause = ex.toString();
ViewUtility.popupInfoMessage(mbean.getInstanceName(), cause);
}
else if (ex instanceof JMException)
{
ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Management Exception occured \n" + ex.toString());
}
else if (ex instanceof ManagementConsoleException)
{
ViewUtility.popupErrorMessage(mbean.getInstanceName(), ex.getMessage());
}
else
{
if (ex.getCause() != null)
{
handleException(mbean, ex.getCause());
}
else
{
String msg = ex.getMessage();
if (msg == null)
{
msg = ex.toString();
}
ViewUtility.popupErrorMessage(mbean.getInstanceName(), msg);
printStackTrace(ex);
}
}
}
/**
* Registers the notification listener with the MBeanServer
* @param mbean managed bean
* @param name notification name
* @param type notification type
* @throws Exception if server connection is broken or if listener could not be created
*/
public static void createNotificationlistener(ManagedBean mbean, String name, String type)
throws Exception
{
JMXManagedObject jmxbean = (JMXManagedObject)mbean;
JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
serverRegistry.addNotificationListener(mbean, name, type);
MBeanServerConnection mbsc = serverRegistry.getServerConnection();
if (mbsc == null)
{
throw new ManagementConsoleException("Server connection is broken");
}
mbsc.addNotificationListener(jmxbean.getObjectName(), serverRegistry.getNotificationListener(), null, null);
}
public static void removeNotificationListener(ManagedBean mbean, String name, String type) throws Exception
{
JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
serverRegistry.removeNotificationListener(mbean, name, type);
}
/**
* Checks if the server registry contains attribute information for this mbean. If not then it queries the
* mbean server for complete mbean information, else it gets the latest value of the given attribute
* from mbean server.
* @return attribute data for the given mbean attribute
*/
public static AttributeData getAttributeData(ManagedBean mbean, String attribute) throws Exception
{
JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean);
if (attributeModel == null)
{
// If process is here, it means the mbeanInfo is not retrieved from mbean server even once for this mbean
getMBeanInfo(mbean);
}
else
{
// refresh attribute value from mbean server
refreshAttribute(mbean, attribute);
}
attributeModel = serverRegistry.getAttributeModel(mbean);
return attributeModel.getAttribute(attribute);
}
/**
* Retrieves the latest attribute value from mbean server for the given mbean attribute
* and also sets that value in the attribute model in the server registry
* @return latest attribute value for the given mbean attribute
*/
public static Object refreshAttribute(ManagedBean mbean, String attribute) throws Exception
{
JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
MBeanServerConnection mbsc = serverRegistry.getServerConnection();
if (mbsc == null)
{
throw new ManagementConsoleException("Server connection is broken");
}
Object value = mbsc.getAttribute(((JMXManagedObject)mbean).getObjectName(), attribute);
// update the attribute data in server registry for this attribute
ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean);
attributeModel.setAttributeValue(attribute, value);
return value;
}
/**
* Retrieves the attribute values from MBeanSever and stores in the server registry.
* @param mbean
* @return the attribute model
* @throws Exception if attributes can not be retrieved from MBeanServer
*/
public static ManagedAttributeModel getAttributes(ManagedBean mbean) throws Exception
{
ObjectName objName = ((JMXManagedObject)mbean).getObjectName();
String[] attributes = null;
AttributeList list = null;
JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
MBeanServerConnection mbsc = serverRegistry.getServerConnection();
MBeanAttributeInfo[] attributesInfo = null;
ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean);
if (attributeModel == null)
{
// If the process is here, then it means the attribute values are not retrieved from mbean server
// even once for this mbean. Create attribute model, retrieve values from mbean server and
// set the attribute model in server registry for this mbean
attributeModel = new ManagedAttributeModel();
attributesInfo = serverRegistry.getMBeanInfo(mbean).getAttributes();
attributes = new String[attributesInfo.length];
for (int i = 0; i< attributesInfo.length ; i++)
{
attributes[i] = attributesInfo[i].getName();
attributeModel.setAttributeDescription(attributes[i], attributesInfo[i].getDescription());
attributeModel.setAttributeWritable(attributes[i], attributesInfo[i].isWritable());
attributeModel.setAttributeReadable(attributes[i], attributesInfo[i].isReadable());
}
}
else
{
attributes = attributeModel.getAttributeNames().toArray(new String[0]);
}
if (attributes.length != 0)
{
list = mbsc.getAttributes(objName, attributes);
for (Iterator itr = list.iterator(); itr.hasNext();)
{
Attribute attrib = (Attribute)itr.next();
attributeModel.setAttributeValue(attrib.getName(), attrib.getValue());
}
}
serverRegistry.setAttributeModel(mbean, attributeModel);
return attributeModel;
}
/**
* Updates the attribute value of an MBean
* @param mbean
* @param attribute
* @param value
* @throws Exception if MBeanServer throws exception in updating the attribute value
*/
public static void updateAttribute(ManagedBean mbean, AttributeData attribute, String value) throws Exception
{
JMXManagedObject jmxbean = (JMXManagedObject)mbean;
JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
MBeanServerConnection mbsc = serverRegistry.getServerConnection();
Object newValue = value;
if (attribute.getDataType().equals(Long.class.getName()))
{
if (MAX_LONG.compareTo(new BigInteger(value)) == -1)
{
throw new ManagementConsoleException("Entered value is too big for \"" +
ViewUtility.getDisplayText(attribute.getName()) + "\"");
}
newValue = new Long(Long.parseLong(value));
}
else if (attribute.getDataType().equals(Integer.class.getName()))
{
if (MAX_INT.compareTo(new BigInteger(value)) == -1)
{
throw new ManagementConsoleException("Entered value is too big for " + attribute.getName());
}
newValue = new Integer(Integer.parseInt(value));
}
mbsc.setAttribute(jmxbean.getObjectName(), new Attribute(attribute.getName(), newValue));
// Update the value in the registry, to avoid refreshing from mbsc
ManagedAttributeModel attributeModel = serverRegistry.getAttributeModel(mbean);
attributeModel.setAttributeValue(attribute.getName(), newValue);
}
/**
* populates the operation data model in server registry for given mbean
* @param mbean
* @return operation data model
*/
public static OperationDataModel getOperations(ManagedBean mbean)
{
JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
OperationDataModel dataModel = serverRegistry.getOperationModel(mbean);
if (dataModel == null)
{
// Create operation model and set it in server registry for this mbean
MBeanOperationInfo[] operationsInfo = serverRegistry.getMBeanInfo(mbean).getOperations();
dataModel = new OperationDataModel();
for (int i = 0; i < operationsInfo.length; i++)
{
dataModel.addOperation(operationsInfo[i]);
}
serverRegistry.setOperationModel(mbean, dataModel);
}
return dataModel;
}
/**
* populates the notification in the server registry for given mbean
* @param mbean
* @return notification info model
*/
public static NotificationInfoModel[] getNotificationInfo(ManagedBean mbean)
{
JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
MBeanNotificationInfo[] info = serverRegistry.getMBeanInfo(mbean).getNotifications();
// Check if this mbean sends any notification
if (info == null || info.length == 0)
return null;
// Create notification model if not already set in the server registry for this mbean
List<NotificationInfoModel> list = serverRegistry.getNotificationInfo(mbean);
if (list != null)
return list.toArray(new NotificationInfoModel[0]);
else
list = new ArrayList<NotificationInfoModel>();
for (int i = 0; i < info.length; i++)
{
list.add(new NotificationInfoModel(info[i].getName(), info[i].getDescription(), info[i].getNotifTypes()));
}
// Set the notification model in the server registry for this mbean
serverRegistry.setNotificationInfo(mbean, list);
return list.toArray(new NotificationInfoModel[0]);
}
/**
* Retrieves all the MBeans from mbean server for a given domain
* @return list of ManagedBeans
*/
public static List<ManagedBean> getManagedObjectsForDomain(ManagedServer server, String domain) throws Exception
{
List<ManagedBean> mbeans = new ArrayList<ManagedBean>();
JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
MBeanServerConnection mbsc = serverRegistry.getServerConnection();
ObjectName objName = new ObjectName(domain + ":*");
Set objectInstances = mbsc.queryMBeans(objName, null);
for (Iterator itr = objectInstances.iterator(); itr.hasNext();)
{
ObjectInstance instance = (ObjectInstance)itr.next();
ManagedBean obj = new JMXManagedObject(instance.getObjectName());
mbeans.add(obj);
}
return mbeans;
}
/**
* Returns all the domains for the given server. This method can be removed as now this RCP is specific to
* Qpid and domain is also fixed
*/
public static List<String> getAllDomains(ManagedServer server) throws Exception
{
JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
MBeanServerConnection mbsc = serverRegistry.getServerConnection();
String[] domains = mbsc.getDomains();
return Arrays.asList(domains);
}
public static void printOutput(String statement)
{
if (ApplicationRegistry.debug)
{
System.out.println(statement);
}
}
public static void printStackTrace(Throwable ex)
{
if (ApplicationRegistry.debug)
{
ex.printStackTrace();
}
}
}