package org.mobicents.slee.container.deployment.jboss; import javax.management.InstanceNotFoundException; import javax.management.ListenerNotFoundException; import javax.management.MBeanException; import javax.management.MBeanServer; import javax.management.MBeanServerNotification; import javax.management.MalformedObjectNameException; import javax.management.Notification; import javax.management.NotificationListener; import javax.management.ObjectName; import javax.management.ReflectionException; import javax.slee.management.SleeManagementMBean; import javax.slee.management.SleeState; import javax.slee.management.SleeStateChangeNotification; import org.apache.log4j.Logger; import org.jboss.mx.util.MBeanServerLocator; /** * JMX Client that, through JMX subscriptions, knows if the SLEE container is in running state. * * @author martins * */ public class SleeStateJMXMonitor implements NotificationListener { private static final Logger logger = Logger.getLogger(SleeStateJMXMonitor.class); private final DeploymentManager deploymentManager; private SleeState sleeState = SleeState.STOPPED; /** * @param deploymentManager */ public SleeStateJMXMonitor(DeploymentManager deploymentManager) { this.deploymentManager = deploymentManager; } private final static Object[] EMPTY_OBJECT_ARRAY = new Object[0]; private final static String[] EMPTY_STRING_ARRAY = new String[0]; private boolean registredSleeManagementMBeanNotificationListener = false; /** * * @return */ public SleeState getSleeState() { synchronized (this) { if(!registredSleeManagementMBeanNotificationListener) { try { // find mbean server final MBeanServer server = MBeanServerLocator.locateJBoss(); // register for notifications when an mbean is registered on server server.addNotificationListener(ObjectName.getInstance("JMImplementation:type=MBeanServerDelegate"), this, null, null); // check slee mngmnt mbean is registred final ObjectName sleeManagementMbeanObjectName = ObjectName.getInstance(SleeManagementMBean.OBJECT_NAME); if (server.isRegistered(sleeManagementMbeanObjectName) && !registredSleeManagementMBeanNotificationListener) { registerSleeManagementMBeanNotificationListener(server, sleeManagementMbeanObjectName); } // else we wait for notification regarding its registration } catch (Throwable e) { logger.error(e.getMessage(),e); } } return this.sleeState; } } private void registerSleeManagementMBeanNotificationListener(MBeanServer server, ObjectName sleeManagementMbeanObjectName) throws ListenerNotFoundException, InstanceNotFoundException, MalformedObjectNameException, NullPointerException, ReflectionException, MBeanException { if(!registredSleeManagementMBeanNotificationListener) { // ok, we don't need to know when an mbean registers in server anymore try { server.removeNotificationListener(ObjectName.getInstance("JMImplementation:type=MBeanServerDelegate"), this); } catch (Throwable e) { logger.warn(e.getMessage(),e); } // but we need to learn when slee state changes server.addNotificationListener(sleeManagementMbeanObjectName, this, null, null); registredSleeManagementMBeanNotificationListener = true; // check if slee state is running SleeState sleeState = (SleeState) server.invoke(sleeManagementMbeanObjectName,"getState",EMPTY_OBJECT_ARRAY,EMPTY_STRING_ARRAY); setSleeState(sleeState); } } private void setSleeState(SleeState sleeState) { if (logger.isDebugEnabled()) { logger.debug("setSleeState: value = "+sleeState.toString()); } if (this.sleeState != sleeState) { this.sleeState = sleeState; if (sleeState == SleeState.RUNNING) { deploymentManager.sleeIsRunning(); } } } /* (non-Javadoc) * @see javax.management.NotificationListener#handleNotification(javax.management.Notification, java.lang.Object) */ public void handleNotification(final Notification notification, Object handback) { // do in a new thread to avoid txs from mbean server Runnable runnable = new Runnable() { public void run() { synchronized (SleeStateJMXMonitor.this) { if (notification instanceof SleeStateChangeNotification) { if (logger.isDebugEnabled()) { logger.debug("received slee state change jmx notification "+notification); } SleeStateChangeNotification sscn = (SleeStateChangeNotification) notification; setSleeState(sscn.getNewState()); } else if (notification instanceof MBeanServerNotification) { MBeanServerNotification mbsn = (MBeanServerNotification) notification; try { final ObjectName sleeManagementMbeanObjectName = ObjectName.getInstance(SleeManagementMBean.OBJECT_NAME); if (mbsn.getType().equals(MBeanServerNotification.REGISTRATION_NOTIFICATION) && mbsn.getMBeanName().equals(sleeManagementMbeanObjectName)) { if (logger.isDebugEnabled()) { logger.debug("received slee management mbean registration jmx notification "+notification); } registerSleeManagementMBeanNotificationListener(MBeanServerLocator.locateJBoss(),sleeManagementMbeanObjectName); } } catch (Throwable e) { logger.error(e.getMessage(),e); } } } } }; new Thread(runnable).start(); } }