BarrierController.java |
/* * JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. * See terms of license at gnu.org. * */ package org.jboss.system; import javax.management.Notification; import javax.management.ObjectName; /** * BarrierController service. * * A service that controls the lifecycle of a secondary mbean * (the BarrierMbean) that can be used as a dependency for other * services. * * Starting and stopping the barrier mbean (and as a result * all services depending on it) is performed by listening * for any kind of JMX notification. In particular we use * the handback object of a notification subscription to * qualify the start and stop signals. * * Manual control of the barrier is also supported through * startBarrier()/stopBarrier() methods. * * You may subclass BarrierController and override enableOnStartup() * to apply complex logic in deciding whether to initially start * the barrier (e.g. query some other mbean). * * @jmx:mbean * extends="org.jboss.system.ListenerServiceMBean" * name="jboss:service=BarrierController" * * @author <a href="dimitris@jboss.org">Dimitris Andreadis</a> * @author Scott.Stark@jboss.org * @version $Revision: 1.2.4.2 $ */ public class BarrierController extends ListenerServiceMBeanSupport implements BarrierControllerMBean { // Private Data -------------------------------------------------- /** The ObjectName of the Barrier MBean */ private ObjectName barrierName; /** The initial state of the barrier */ private Boolean enableOnStartup; /** The notification subscription handback string that starts the barrier */ private String startHandback; /** The notification subscription handback string that stops the barrier */ private String stopHandback; /** The dynamic subscriptions flag */ private Boolean dynamicSubscriptions; // Protected Data ------------------------------------------------ /** The controlled Barrier */ protected Barrier barrier; // Constructors -------------------------------------------------- /** * Default CTOR */ public BarrierController() { // empty } // Attributes ---------------------------------------------------- /** * The controlled barrier StateString. * * @jmx.managed-attribute */ public String getBarrierStateString() { return (barrier != null) ? barrier.getStateString() : null; } /** * The controlled barrier ObjectName. * * @jmx.managed-attribute */ public void setBarrierObjectName(ObjectName barrierName) { // set once if (this.barrierName == null) { this.barrierName = barrierName; } } /** * The controlled barrier ObjectName. * * @jmx.managed-attribute */ public ObjectName getBarrierObjectName() { return barrierName; } /** * The initial state of the barrier. * * If set, it overrides the internal call to enableOnStartup() * which will never get called. * * @jmx.managed-attribute */ public void setBarrierEnabledOnStartup(Boolean enableOnStartup) { // set once if (this.enableOnStartup == null) { this.enableOnStartup = enableOnStartup; } } /** * The initial state of the barrier. * * Use the value set through setBarrierEnabledOnStartup() * otherwise call the internal enableOnStartup() override * to make a decision. * * @jmx.managed-attribute */ public Boolean getBarrierEnabledOnStartup() { if (enableOnStartup == null) { // setBarrierEnabledOnStartup() not called // initialize through enableOnStartup() enableOnStartup = enableOnStartup(); } return enableOnStartup; } /** * The notification subscription handback string that starts the barrier. * * @jmx.managed-attribute */ public void setStartBarrierHandback(String startHandback) { // set once if (this.startHandback == null) { this.startHandback = startHandback; } } /** * The notification subscription handback string that starts the barrier. * * @jmx.managed-attribute */ public String getStartBarrierHandback() { return startHandback; } /** * The notification subscription handback string that stops the barrier. * * @jmx.managed-attribute */ public void setStopBarrierHandback(String stopHandback) { // set once if (this.stopHandback == null) { this.stopHandback = stopHandback; } } /** * The notification subscription handback string that stops the barrier. * * @jmx.managed-attribute */ public String getStopBarrierHandback() { return stopHandback; } /** * The ability to dynamically subscribe for notifications. * * @jmx.managed-attribute */ public void setDynamicSubscriptions(Boolean dynamicSubscriptions) { // set once if (this.dynamicSubscriptions == null) { this.dynamicSubscriptions = dynamicSubscriptions; } } /** * The ability to dynamically subscribe for notifications. * * @jmx.managed-attribute */ public Boolean getDynamicSubscriptions() { if (dynamicSubscriptions == null) { dynamicSubscriptions = Boolean.TRUE; } return dynamicSubscriptions; } // Override ------------------------------------------------------ /** * Override this method to apply complex logic whether * to start the Barrier service upon startup or not. * * This method will be only called once and only if * setBarrierEnabledOnStartup(Boolean) has not been called. * * The default implementation is to return false. */ protected Boolean enableOnStartup() { return Boolean.FALSE; } // Lifecycle ----------------------------------------------------- protected void createService() throws Exception { // create the Barrier barrier = new Barrier(getServiceName()); // register with the MBeanServer getServer().registerMBean(barrier, barrierName); // implicitly call the ServiceController barrier.create(); // conditionally start the barrier if (getBarrierEnabledOnStartup().booleanValue()) { startBarrier(); } // subscribe for notifications subscribe(getDynamicSubscriptions().booleanValue()); } protected void destroyService() { // unsubscribe for notifications unsubscribe(); try { // implicitly call the ServiceController barrier.destroy(); // remove from MBeanServer getServer().unregisterMBean(barrierName); } catch (Throwable e) { log.debug("Unexpected error during destroy", e); } // cleanup barrier = null; } // ListenerServiceMBeanSupport ----------------------------------- /** * Base on the handback object the decision * for starting/stopping the barrier */ public void handleNotification2(Notification n, Object handback) { log.debug("Got notification: " + n); if (startHandback != null && startHandback.equals(handback)) { log.debug("Saw '" + handback + "' handback, starting barrier"); startBarrier(); } else if (stopHandback != null && stopHandback.equals(handback)) { log.debug("Saw '" + handback + "' handback, stopping barrier"); stopBarrier(); } } // Operations ---------------------------------------------------- /** * Manually start the controlled barrier * * @jmx:managed-operation */ public void startBarrier() { try { // implicitly call the ServiceController barrier.start(); } catch (Throwable e) { log.warn("Failed to start barrier: " + barrierName, e); } } /** * Manually stop the controlled barrier * * @jmx:managed-operation */ public void stopBarrier() { try { // implicitly call the ServiceController barrier.stop(); } catch (Throwable e) { log.warn("Failed to stop barrier: " + barrierName, e); } } // Inner Class --------------------------------------------------- /** * The controlled barrier MBean interface */ public static interface BarrierMBean { /** We just want to expose those attributes */ ObjectName getBarrierController(); String getStateString(); int getState(); /** Hook up with the ServiceController */ void jbossInternalLifecycle(String method) throws Exception; } /** * The controlled barrier MBean class */ public static class Barrier extends ServiceMBeanSupport implements BarrierMBean { /** The parent Controller */ private ObjectName barrierController; /** CTOR */ public Barrier(ObjectName barrierController) { this.barrierController = barrierController; } /** Accessor */ public ObjectName getBarrierController() { return barrierController; } } }
BarrierController.java |