package com.plexobject.rbac.jmx; import java.lang.management.ManagementFactory; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.management.InstanceAlreadyExistsException; import javax.management.JMRuntimeException; import javax.management.MBeanServer; import javax.management.MBeanServerFactory; import javax.management.ObjectName; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.validator.GenericValidator; import org.apache.log4j.Logger; import com.plexobject.rbac.jmx.impl.Log4jJMXBeanImpl; import com.plexobject.rbac.jmx.impl.ServiceJMXBeanImpl; /** * This class registers service-mbeans to the local mbean server Use following * system arguments -Dcom.sun.management.jmxremote.port=<port> \ * -Dcom.sun.management.jmxremote.authenticate=false \ * -Dcom.sun.management.jmxremote.ssl=false * */ public class JMXRegistrar { private static final Logger LOGGER = Logger.getLogger(JMXRegistrar.class); private MBeanServer mbeanServer; private static final JMXRegistrar INSTANCE = new JMXRegistrar(); private Map<String, ServiceJMXBeanImpl> mbeans = new ConcurrentHashMap<String, ServiceJMXBeanImpl>(); public static JMXRegistrar getInstance() { return INSTANCE; } /** * * @param serviceClass * -- service class * @return instance of ServiceJMXBean */ public ServiceJMXBeanImpl register(final Class<?> serviceClass) { return register(serviceClass.getPackage().getName() + ":type=" + serviceClass.getSimpleName()); } public Collection<ServiceJMXBeanImpl> getServiceJMXBeans() { return Collections.unmodifiableCollection(mbeans.values()); } /** * * @param serviceName * -- name of service (that is also used as object name) * @return instance of ServiceJMXBean */ public ServiceJMXBeanImpl register(final String serviceName) { if (GenericValidator.isBlankOrNull(serviceName)) { throw new IllegalArgumentException("serviceName not specified"); } synchronized (serviceName.intern()) { ServiceJMXBeanImpl mbean = mbeans.get(serviceName); if (mbean == null) { mbean = new ServiceJMXBeanImpl(serviceName); mbeans.put(serviceName, mbean); try { ObjectName name = new ObjectName(serviceName); mbeanServer.registerMBean(mbean, name); if (LOGGER.isInfoEnabled()) { LOGGER.info("regstered MXBean " + serviceName); } } catch (InstanceAlreadyExistsException e) { } catch (Exception e) { throw new JMRuntimeException("Failed to register " + serviceName + " due to " + e); } } return mbean; } } /** * @see java.lang.Object#equals(Object) */ @Override public boolean equals(Object object) { if (!(object instanceof JMXRegistrar)) { return false; } JMXRegistrar rhs = (JMXRegistrar) object; return new EqualsBuilder().append(this.mbeanServer, rhs.mbeanServer) .isEquals(); } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return new HashCodeBuilder(786529047, 1924536713).append(mbeanServer) .toHashCode(); } /** * @see java.lang.Object#toString() */ @Override public String toString() { return new ToStringBuilder(this) .append("mbeanServer", this.mbeanServer).toString(); } JMXRegistrar() { mbeanServer = ManagementFactory.getPlatformMBeanServer(); if (mbeanServer == null) { List<MBeanServer> existingServers = MBeanServerFactory .findMBeanServer(null); if (!existingServers.isEmpty()) { mbeanServer = existingServers.get(0); } else { mbeanServer = MBeanServerFactory.createMBeanServer(); } } // registering log4j mbean final Log4jJMXBeanImpl mbean = new Log4jJMXBeanImpl(); ObjectName name; try { name = new ObjectName(mbean.getObjectName()); mbeanServer.registerMBean(mbean, name); } catch (Exception e) { LOGGER.error("Failed to register log4j-mbean", e); } } }