package org.jgroups.jmx;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jgroups.annotations.MBean;
import org.jgroups.stack.Protocol;
import org.jgroups.stack.ProtocolStack;
import javax.management.*;
import java.lang.management.ManagementFactory;
import java.util.Vector;
import java.util.Set;
import java.util.Iterator;
/**
* @author Bela Ban
* @version $Id: JmxConfigurator.java,v 1.13 2008/03/13 02:42:57 vlada Exp $
*/
public class JmxConfigurator {
static final Log log=LogFactory.getLog(JmxConfigurator.class);
/**
* Registers an already created channel with the MBeanServer. Creates an
* org.jgroups.jmx.JChannel which delegates to the org.jgroups.JChannel and
* registers it. Optionally, this method will also try to create one MBean
* proxy for each protocol in the channel's protocol stack, and register it
* as well.
*
* @param channel
* @param server
* @param domain
* Has to be a JMX ObjectName of the domain, e.g.
* DefaultDomain:name=JGroups
* @param register_protocols
* @return org.jgroups.jmx.JChannel for the specified org.jgroups.JChannel
*/
public static void registerChannel(org.jgroups.JChannel channel,
MBeanServer server,
String domain,
String cluster_name,
boolean register_protocols) throws Exception {
if(cluster_name == null)
cluster_name=channel != null? channel.getClusterName() : null;
if(cluster_name == null)
cluster_name="null";
if(register_protocols) {
ProtocolStack stack=channel.getProtocolStack();
Vector<Protocol> protocols=stack.getProtocols();
for(Protocol p:protocols) {
register(p,
ManagementFactory.getPlatformMBeanServer(),
getProtocolRegistrationName(cluster_name, domain, p));
}
}
register(channel, server, getChannelRegistrationName(channel, domain, cluster_name));
}
/**
* Registers an already created channel with the MBeanServer. Creates an
* org.jgroups.jmx.JChannel which delegates to the org.jgroups.JChannel and
* registers it.
*
* @param channel
* @param server
* @param name
* The JMX ObjectName
* @return org.jgroups.jmx.JChannel for the specified org.jgroups.JChannel
*/
public static void registerChannel(org.jgroups.JChannel channel, MBeanServer server, String name) throws Exception {
registerChannel(channel, server, "jgroups", name, true);
}
public static void unregisterChannel(MBeanServer server, ObjectName name) throws Exception {
if(server != null)
server.unregisterMBean(name);
}
public static void unregisterChannel(MBeanServer server, String name) throws Exception {
if(server != null)
server.unregisterMBean(new ObjectName(name));
}
public static void unregisterChannel(org.jgroups.JChannel c,
MBeanServer server,
String clusterName) throws Exception {
ProtocolStack stack=c.getProtocolStack();
Vector<Protocol> protocols=stack.getProtocols();
for(Protocol p:protocols) {
if(p.getClass().isAnnotationPresent(MBean.class)) {
try {
unregister(p,
ManagementFactory.getPlatformMBeanServer(),
getProtocolRegistrationName(clusterName, "jgroups", p));
}
catch(MBeanRegistrationException e) {
if(log.isWarnEnabled()) {
log.warn("MBean unregistration failed " + e);
}
}
}
}
unregister(c, server, getChannelRegistrationName(clusterName));
}
public static void registerChannelFactory(org.jgroups.JChannelFactory factory,
MBeanServer server,
String name) throws Exception {
register(factory, server, name);
}
public static void unRegisterChannelFactory(org.jgroups.JChannelFactory factory,
MBeanServer server,
String name) throws Exception {
unregister(factory, server, name);
}
public static void register(Object obj, MBeanServer server, String name) throws MBeanRegistrationException,
MalformedObjectNameException {
internalRegister(obj, server, name);
}
public static void unregister(Object obj, MBeanServer server, String name) throws MBeanRegistrationException,
MalformedObjectNameException {
internalUnregister(obj, server, name);
}
private static void internalRegister(Object obj, MBeanServer server, String name) throws MalformedObjectNameException,
MBeanRegistrationException {
if(obj == null)
throw new IllegalArgumentException("Object being registered cannot be null");
if(server == null)
throw new IllegalArgumentException("MBean server used for registeration cannot be null");
try {
ObjectName objName=getObjectName(obj, name);
ResourceDMBean res=new ResourceDMBean(obj);
server.registerMBean(res, objName);
if(log.isDebugEnabled()) {
log.debug("register MBean " + objName + " completed");
}
}
catch(InstanceAlreadyExistsException e) {
if(log.isErrorEnabled()) {
log.error("register MBean failed " + e.getMessage());
}
throw new MBeanRegistrationException(e, "The @MBean objectName is not unique");
}
catch(NotCompliantMBeanException e) {
if(log.isErrorEnabled()) {
log.error("register MBean failed " + e.getMessage());
}
throw new MBeanRegistrationException(e);
}
}
private static void internalUnregister(Object obj, MBeanServer server, String name) throws MBeanRegistrationException {
try {
if(name != null && name.length() > 0) {
server.unregisterMBean(new ObjectName(name));
}
else if(obj != null) {
server.unregisterMBean(getObjectName(obj, null));
}
else {
throw new MBeanRegistrationException(null,
"Cannot find MBean name from @MBean or passed in value");
}
if(log.isDebugEnabled()) {
log.debug("unregister MBean" + name + " completed");
}
}
catch(InstanceNotFoundException infe) {
if(log.isErrorEnabled()) {
log.error("unregister MBean failed " + infe.getMessage());
}
throw new MBeanRegistrationException(infe);
}
catch(MalformedObjectNameException e) {
if(log.isErrorEnabled()) {
log.error("unregister MBean failed " + e.getMessage());
}
throw new MBeanRegistrationException(e);
}
}
private static ObjectName getObjectName(Object obj, String name) throws MalformedObjectNameException {
MBean resource=obj.getClass().getAnnotation(MBean.class);
if(name != null && name.length() > 0) {
return new ObjectName(name);
}
else if(resource.objectName() != null && resource.objectName().length() > 0) {
return new ObjectName(resource.objectName());
}
else {
throw new MalformedObjectNameException("Instance " + obj
+ " of a class "
+ obj.getClass()
+ " does not have a valid object name");
}
}
/**
* Unregisters object_name and everything under it
*
* @param object_name
*/
public static void unregister(MBeanServer server, String object_name) throws Exception {
Set mbeans=server.queryNames(new ObjectName(object_name), null);
if(mbeans != null) {
ObjectName name;
for(Iterator it=mbeans.iterator();it.hasNext();) {
name=(ObjectName)it.next();
server.unregisterMBean(name);
}
}
}
private static String getChannelRegistrationName(org.jgroups.JChannel c,
String domain,
String clusterName) {
return domain + ":type=channel,cluster=" + clusterName;
}
private static String getProtocolRegistrationName(String clusterName, String domain, Protocol p) {
return domain + ":type=protocol,cluster=" + clusterName + ",protocol=" + p.getName();
}
private static String getChannelRegistrationName(String clusterName) {
return "jgroups:type=channel,cluster=" + clusterName;
}
}