User: mnf999  
  Date: 01/12/18 22:26:19

  Modified:    src/main/org/jboss/system ServiceController.java
  Log:
  The ServiceController logic, start and stop dependent beans automatically, 
simplified logic
  
  Revision  Changes    Path
  1.17      +494 -518  jboss/src/main/org/jboss/system/ServiceController.java
  
  Index: ServiceController.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/system/ServiceController.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- ServiceController.java    2001/11/30 15:49:35     1.16
  +++ ServiceController.java    2001/12/19 06:26:19     1.17
  @@ -1,9 +1,9 @@
   /*
  - * JBoss, the OpenSource J2EE webOS
  - *
  - * Distributable under LGPL license.
  - * See terms of license at gnu.org.
  - */
  +* JBoss, the OpenSource J2EE webOS
  +*
  +* Distributable under LGPL license.
  +* See terms of license at gnu.org.
  +*/
   package org.jboss.system;
   
   
  @@ -15,6 +15,7 @@
   import java.util.HashMap;
   import java.util.Iterator;
   import java.util.List;
  +import java.util.LinkedList;
   import java.util.ListIterator;
   import java.util.Map;
   import javax.management.InstanceNotFoundException;
  @@ -31,152 +32,130 @@
   import javax.management.RuntimeErrorException;
   import javax.management.RuntimeMBeanException;
   import javax.management.RuntimeOperationsException;
  +
   import org.w3c.dom.Element;
   import org.jboss.logging.Logger;
   
   /**
  - * This is the main Service Controller. A controller can deploy a service to a
  - * JBOSS-SYSTEM It installs by delegating, it configures by delegating
  - *
  - * @see org.jboss.system.Service
  - * @author <a href="mailto:[EMAIL PROTECTED]";>Marc Fleury</a>
  - * @author <a href="mailto:[EMAIL PROTECTED]";>David Jencks</a>
  - * @version $Revision: 1.16 $ <p>
  - *
  - * <b>Revisions:</b> <p>
  - *
  - * <b>20010830 marcf</b>
  - * <ol>
  - *   <li>Initial version checked in
  - * </ol>
  - * <b>20010908 david jencks</b>
  - * <ol>
  - *   <li>fixed tabs to spaces and log4j logging. Made it report the number
  - *       of successes on init etc.  Modified to support undeploy and work with
  - *       .sar dependency management and recursive sar deployment.
  - * </ol>
  - */
  +* This is the main Service Controller. A controller can deploy a service to a
  +* JBOSS-SYSTEM It installs by delegating, it configures by delegating
  +*
  +* @see org.jboss.system.Service
  +* @author <a href="mailto:[EMAIL PROTECTED]";>Marc Fleury</a>
  +* @author <a href="mailto:[EMAIL PROTECTED]";>David Jencks</a>
  +* @version $Revision: 1.17 $ <p>
  +*
  +* <b>Revisions:</b> <p>
  +*
  +* <b>20010830 marcf</b>
  +* <ol>
  +*   <li>Initial version checked in
  +* </ol>
  +* <b>20010908 david jencks</b>
  +* <ol>
  +*   <li>fixed tabs to spaces and log4j logging. Made it report the number
  +*       of successes on init etc.  Modified to support remove and work with
  +*       .sar dependency management and recursive sar deployment.
  +* </ol>
  +* <b>2001210 marcf</b>
  +* <ol>
  +*   <li>Rewrite
  +* </ol>
  +*/
   public class ServiceController
  -   //extends ServiceMBeanSupport
  -       implements ServiceControllerMBean, MBeanRegistration
  +//extends ServiceMBeanSupport
  +implements ServiceControllerMBean, MBeanRegistration
   {
  -
  -   private final Logger log = Logger.getLogger(getClass());
  -
  -
  -   /**
  -    * A mapping from the Service interface method names to the corresponding
  -    * index into the ServiceProxy.hasOp array.
  -    */
  -   private static HashMap serviceOpMap = new HashMap();
  -   /**
  -    * Map between mbeans and the mbean references they have
  -    */
  -   private static HashMap mbeanToMBeanRefsMap = new HashMap();
  -   //inverse map
  -   private static HashMap mbeanRefToMBeansMap = new HashMap();
  -
  -   /**
  -    * The set of mbeans that can't find all their mbean references, mapped to 
  -    * the mbeans they can't find.
  -    */
  -   private static HashMap suspendedToMissingMBeanMap = new HashMap();
  -
  -   /**
  -    * The map between missing mbeans and what is waiting for them : 
  -    * inverse of suspendedToMissingMBeanMap
  -    */
  -   private static HashMap missingToSuspendedMBeanMap = new HashMap();
  -
  -
  -   /**
  -    * Helper classes to create and configure the classes
  -    */
  -   protected ServiceCreator creator;
  -   /**
  -    * Description of the Field
  -    */
  -   protected ServiceConfigurator configurator;
  -
      // Attributes ----------------------------------------------------
  -
  +   
  +   private final Logger log = Logger.getLogger(getClass());
  +   
      /** A callback to the JMX MBeanServer */
      MBeanServer server;
  -
  -   /** The array list keeps the order of deployment. */
  -   List startedServices = new ArrayList();
      
  -   /** The map keeps the list of objectNames to services. */
  -   Map nameToServiceMap = new HashMap();
  -
  -   // Static --------------------------------------------------------
  -
  +   /** Creator, helper class to instanciate MBeans **/
  +   protected ServiceCreator creator;
  +   
  +   /** Configurator, helper class to configure MBeans **/
  +   protected ServiceConfigurator configurator;
  +   
  +   /** Object Name to Service Proxy map **/
  +   protected Map nameToServiceMap = new HashMap();
  +   
  +   /** A linked list of services in the order they were created **/
  +   protected List installedServices = new LinkedList();
  +   
  +   
      // Constructors --------------------------------------------------
  -
  +   
      // Public --------------------------------------------------------
  -
  -   public Logger getLog()
  -   {
  -      return log;
  -   }
  -
  -   /**
  -    * Gets the Name attribute of the ServiceController object
  -    *
  -    * @return The Name value
  -    */
  -   public String getName()
  -   {
  -      return "Service Controller";
  -   }
  -
  -
  +   
  +   public Logger getLog() { return log;}
  +   
  +   public String getName() { return "Service Controller"; }
  +   
  +   
      /**
  -    * Gets the Deployed attribute of the ServiceController object
  -    *
  -    * @return The Deployed value
  -    */
  +   * Gets the Deployed attribute of the ServiceController object
  +   *
  +   * @return The Deployed value
  +   */
      public ObjectName[] getDeployed()
      {
  -      ObjectName[] deployed = new ObjectName[startedServices.size()];
  -      startedServices.toArray(deployed);
  -
  +      ObjectName[] deployed = new ObjectName[installedServices.size()];
  +      
  +      ListIterator iterator = installedServices.listIterator();
  +      
  +      for (int i = 0; i<installedServices.size() ; i++)
  +      {
  +         
  +         deployed[i] = ((ServiceContext) iterator.next()).objectName;
  +      
  +      }
  +      
         return deployed;
      }
  -
  +   
      /**
  -    * Gets the Configuration attribute of the ServiceController object
  -    *
  -    * @param objectNames Description of Parameter
  -    * @return The Configuration value
  -    * @exception Exception Description of Exception
  -    */
  +   * Gets the Configuration attribute of the ServiceController object
  +   *
  +   * @param objectNames Description of Parameter
  +   * @return The Configuration value
  +   * @exception Exception Description of Exception
  +   */
      public String getConfiguration(ObjectName[] objectNames) throws Exception
      {
         return configurator.getConfiguration(objectNames);
      }
  -
  +   
      /**
  -    * Deploy the beans
  -    *
  -    * @param mbeanElement Description of Parameter
  -    * @return Description of the Returned Value
  -    * @throws Exception ???
  -    */
  -   public ObjectName deploy(Element mbeanElement)
  -          throws Exception
  +   * Deploy the beans
  +   *
  +   * Deploy means "instanciate and configure" so the MBean is created in the 
MBeanServer
  +   * You must call "create" and "start" separately on the MBean to affect the 
service lifecycle
  +   * deploy doesn't bother with service lifecycle only MBean 
instanciation/registration/configuration
  +   * 
  +   * @param mbeanElement Description of Parameter
  +   * @return Description of the Returned Value
  +   * @throws Exception ???
  +   */
  +   public synchronized ObjectName install(Element mbeanElement)
  +   throws Exception
      {
  -      // The ObjectName of the bean
  -      ObjectName objectName = parseObjectName(mbeanElement);
  +      
  +      // Create a Service Context for the service, or get one if it exists
  +      ServiceContext ctx = getServiceContext(parseObjectName(mbeanElement));
  +      
  +      // MARCF FIXME THINK ABOUT REMOVe IF ACTIVE HERE
         //at least make a new version!
  -      //undeploy(objectName);
  -
  -      // It is not there so really create the component now
  +      //remove(objectName);
  +      
  +      // It is not there so really create the component now, this registers the 
component in the mbeanserver
         try
         {
  -         creator.create(mbeanElement);
  +         creator.install(mbeanElement);
         }
  -
  +      
         catch (MBeanException mbe)
         {
            mbe.getTargetException().printStackTrace();
  @@ -199,211 +178,330 @@
         //
         catch (Throwable e)
         {
  -         log.error("Could not create MBean: " + objectName, e);
  +         log.error("Could not create MBean: " + ctx.objectName, e);
            if (e instanceof Exception)
               throw (Exception)e;
            if (e instanceof Error)
               throw (Error)e;
  +         
            throw new Error("unexpected throwable: " + e);
         }
         
  -      // Configure the MBean
  -      boolean waiting = false;
  -      try
  -      {
  -         ArrayList mBeanRefs = configurator.configure(mbeanElement);
  -         if (mBeanRefs.size() > 0) 
  -         {
  -            synchronized (this)
  -            {
  -               mbeanToMBeanRefsMap.put(objectName, mBeanRefs);
  -               //ArrayList waitingFor = new ArrayList();
  -               Iterator refs = mBeanRefs.iterator();
  -               while (refs.hasNext()) 
  -               {
  -                  //First, record dependencies
  -                  ObjectName ref = (ObjectName)refs.next();
  -                  ArrayList backRefs = (ArrayList)mbeanRefToMBeansMap.get(ref);
  -                  if (backRefs == null) 
  -                  {
  -                     backRefs = new ArrayList();
  -                     mbeanRefToMBeansMap.put(ref, backRefs);
  -                  } // end of if ()
  -                  if (!backRefs.contains(objectName)) 
  -                  {
  -                     backRefs.add(objectName);        
  -                  } // end of if ()   
  -                  //Now, does the needed mbean exist? if not, note suspension.
  -                  //We could use the mbean server or our own service map.
  -                  if (!startedServices.contains(ref)) 
  -                  {
  -                     //Not there, mark suspended.
  -                     markWaiting(ref, objectName);
  -                  } // end of if ()
  -               } // end of while ()
  -            }   
  +      // We got this far
  +      ctx.state = ServiceContext.INSTALLED;
  +      
  +      try { 
            
  -         } // end of if (mBeanRefs.size() > 0)
  +         // Configure the MBean
  +         synchronized (this)
  +         {
  +            
  +            // The return is a list of MBeans this MBean "depends" on
  +            List mbeans = configurator.configure(mbeanElement);
  +            
  +            // Link the dependency me.idependOn(them) and them.dependsOnMe(me)
  +            Iterator iterator = mbeans.iterator();
  +            while (iterator.hasNext()) {
  +               
  +               // We work from the service context, if it doesn't exist yet, we 
have a wrapper (OK)
  +               ServiceContext service = getServiceContext((ObjectName) 
iterator.next());
  +               
  +               // ctx depends on service
  +               ctx.iDependOn.add(service);
  +               
  +               // Service needs to know I depend on him
  +               service.dependsOnMe.add(ctx);
  +            }
  +         } 
         }
         catch (Exception e)
         {
  -         log.error("Could not configure MBean: " + objectName, e);
  -         server.unregisterMBean(objectName);
  +         log.error("Could not configure MBean: " + ctx.objectName, e);
  +         
  +         server.unregisterMBean(ctx.objectName);
  +         
  +         ctx.state = ServiceContext.FAILED ; 
            throw e;
  +      
         }
  -      String serviceFactory = mbeanElement.getAttribute("serviceFactory");
  -      try 
  -      {
  -         registerAndStartService(objectName, serviceFactory);
  -      } 
  -      catch (Exception e) 
  -         //ignore errors, we created the mbean so we have to return the name
  -      {} // end of try-catch
         
  -      return objectName;
  +      // We got this far
  +      ctx.state = ServiceContext.CONFIGURED;
  +      
  +      if ( !installedServices.contains(ctx)) installedServices.add(ctx);
  +         
  +      return ctx.objectName;
      }
  -
  -   //needs to be an mbean method, for e.g. RARDeployer to register RAR's for 
dependency.
  -   //puts a mbean that you created some other way (such as deployed rar) 
  -   //into dependency system so other beans can be started/stopped on its 
  -   //existence (or registration)
  -   public void registerAndStartService(ObjectName serviceName, String 
serviceFactory) throws Exception
  -   {
  -      try 
  -      {
  -         Service service = getServiceInstance(serviceName, serviceFactory);
  -         // Keep track
  -         nameToServiceMap.put(serviceName, service);
  -
  -         start(serviceName);
  -         //You are done
  +   
  +   /**
  +   * #Description of the Method
  +   *
  +   * @param serviceName Description of Parameter
  +   * @exception Exception Description of Exception
  +   */
  +   public synchronized void create(ObjectName serviceName) throws Exception
  +   {
  +      
  +      ServiceContext ctx = (ServiceContext) getServiceContext(serviceName);
  +      
  +      
  +      // Get the fancy service proxy (for the lifecycle API)
  +      ctx.proxy = getServiceProxy(ctx.objectName, null);
  +         
  +      // If we are already created (can happen in dependencies) just return
  +      if (ctx.state == ServiceContext.CREATED || ctx.state == 
ServiceContext.RUNNING) return;
  +         
  +      // JSR 77, and to avoid circular dependencies
  +      int oldState = ctx.state; 
  +      ctx.state= ServiceContext.CREATED;
  +      
  +      // Are all the mbeans I depend on created?   if not just return
  +      Iterator iterator = ctx.iDependOn.iterator();
  +      while (iterator.hasNext())
  +      {
  +         ServiceContext sc = (ServiceContext) iterator.next();
  +         
  +         int state = sc.state;
  +         
  +         // A dependent is not created or running
  +         if (!(state == ServiceContext.CREATED || state == ServiceContext.RUNNING)) 
{
  +            
  +            
  +            log.info("&&&&&&&&&&&&&&&&&&&&&&&&  waiting in create 
"+serviceName.toString() +" waiting on "+sc.objectName);
  +            ctx.state=oldState;
  +            return;
  +         }
         }
  -      catch (Exception e) 
  +      
  +      // Call create on the service Proxy  
  +      try { ctx.proxy.create(); }
  +         
  +      catch (Exception e){ ctx.state = ServiceContext.FAILED; throw e;}
  +      
  +      // Those that depend on me are waiting for my creation, recursively create 
them
  +      Iterator iterator2 = ctx.dependsOnMe.iterator();
  +      while (iterator2.hasNext()) 
         {
  -         log.error("Problem in registerAndStartService", e);
  -         throw e;
  -      } // end of try-catch
  -
  +         // marcf fixme circular dependencies?
  +         create(((ServiceContext) iterator2.next()).objectName);  
  +      }
      }
  +   
  +   
  +   
      /**
  -    * #Description of the Method
  -    *
  -    * @param mbeanElement Description of Parameter
  -    * @exception Exception Description of Exception
  -    */
  -   public void undeploy(Element mbeanElement) throws Exception
  +   * #Description of the Method
  +   *
  +   * @param serviceName Description of Parameter
  +   * @exception Exception Description of Exception
  +   */
  +   public synchronized void start(ObjectName serviceName) throws Exception
      {
  -
  -      undeploy(parseObjectName(mbeanElement));
  +      
  +      ServiceContext ctx = (ServiceContext) getServiceContext(serviceName);
  +      
  +      // If we are already started (can happen in dependencies) just return
  +      if (ctx.state == ServiceContext.RUNNING) return;
  +         
  +      // JSR 77, and to avoid circular dependencies
  +      int oldState = ctx.state; 
  +      ctx.state= ServiceContext.RUNNING;
  +      
  +      // Are all the mbeans I depend on created?   if not just return
  +      Iterator iterator = ctx.iDependOn.iterator();
  +      while (iterator.hasNext())
  +      {
  +         ServiceContext sctx = (ServiceContext) iterator.next();
  +         
  +         int state  = sctx.state;
  +         
  +         // A dependent is not running
  +         if (!(state == ServiceContext.RUNNING))
  +         {
  +            ObjectName cac = new ObjectName("Test:name=test");
  +            ObjectName ca2 = new ObjectName("Test:name=test");
  +            
  +            log.info("%%%%%%%%%%%%%%%%%%   waiting in 
start"+serviceName.toString()+" on "+sctx.objectName);
  +            
  +            ctx.state=oldState;
  +            return;
  +         }
  +      }
  +      
  +      // Call create on the service Proxy  
  +      try { ctx.proxy.start(); }
  +         
  +      catch (Exception e){ ctx.state = ServiceContext.FAILED; throw e;}
  +      
  +      // JSR 77
  +      ctx.state = ServiceContext.RUNNING;
  +      
  +      installedServices.add(ctx.objectName);
  +      
  +      // Those that depend on me are waiting for my creation, recursively create 
them
  +      Iterator iterator2 = ctx.dependsOnMe.iterator();
  +      while (iterator2.hasNext()) 
  +      {
  +         // marcf fixme circular dependencies?
  +         start(((ServiceContext) iterator2.next()).objectName);  
  +      }
      }
  -
  -
  +   
      /**
  -    * #Description of the Method
  -    *
  -    * @param objectName Description of Parameter
  -    * @exception Exception Description of Exception
  -    */
  -   public void undeploy(ObjectName objectName) throws Exception
  -   {
  -      try 
  -      {
  -         stop(objectName);
  -      } 
  -      catch (Exception e) 
  -      { } // end of try-catch
  -      //We are not needing anyone or waiting for anyone
  -      ArrayList weNeededList = (ArrayList)mbeanToMBeanRefsMap.remove(objectName);
  -      if (weNeededList != null) 
  -      {
  -         //remove the back reference for each mbean we needed.
  -         Iterator needed = weNeededList.iterator();
  -         while (needed.hasNext()) 
  +   * #Description of the Method
  +   *
  +   * @param serviceName Description of Parameter
  +   * @exception Exception Description of Exception
  +   */
  +   public void stop(ObjectName serviceName) throws Exception
  +   {
  +      
  +      ServiceContext ctx = (ServiceContext) nameToServiceMap.get(serviceName);
  +      
  +      if (ctx != null) 
  +      {
  +         // If we are already stopped (can happen in dependencies) just return
  +         if (ctx.state == ServiceContext.STOPPED) return;
  +            
  +         // JSR 77 and to avoid circular dependencies
  +         ctx.state = ServiceContext.STOPPED;
  +         
  +         Iterator iterator = ctx.dependsOnMe.iterator();
  +         while (iterator.hasNext())
            {
  -            ObjectName neededName = (ObjectName)needed.next();
  -            ArrayList needingList = (ArrayList)mbeanRefToMBeansMap.get(neededName);
  -            if (needingList != null) 
  -            {
  -               needingList.remove(objectName);
  -            } // end of if ()
               
  -         } // end of while ()
  +            // stop all the mbeans that depend on me
  +            stop(((ServiceContext) iterator.next()).objectName);  
  +         }
            
  -      } // end of if ()
  +         // Call create on the service Proxy  
  +         try { ctx.proxy.stop(); }
  +            
  +         catch (Exception e){ ctx.state = ServiceContext.FAILED; throw e;}
  +      
  +      
  +      
  +      }
  +   
  +   }   
  +   
  +   /**
  +   * #Description of the Method
  +   *
  +   * @param serviceName Description of Parameter
  +   * @exception Exception Description of Exception
  +   */
  +   public void destroy(ObjectName serviceName) throws Exception
  +   {
  +      
  +      ServiceContext ctx = (ServiceContext) nameToServiceMap.get(serviceName);
         
  -      ArrayList weSuspendedForList = 
(ArrayList)suspendedToMissingMBeanMap.remove(objectName);
  -      if (weSuspendedForList != null) 
  +      if (ctx != null) 
         {
  -         //remove the back reference for each mbean we suspended for.
  -         Iterator suspendedFor = weSuspendedForList.iterator();
  -         while (suspendedFor.hasNext()) 
  +         // If we are already destroyed (can happen in dependencies) just return
  +         if (ctx.state == ServiceContext.DESTROYED) return;
  +            
  +         // JSR 77, and to avoid circular dependencies
  +         ctx.state = ServiceContext.DESTROYED;
  +         
  +         Iterator iterator = ctx.dependsOnMe.iterator();
  +         while (iterator.hasNext())
            {
  -            ObjectName suspendedForName = (ObjectName)suspendedFor.next();
  -            ArrayList suspendedOnList = 
(ArrayList)missingToSuspendedMBeanMap.get(suspendedForName);
  -            if (suspendedOnList != null) 
  -            {
  -               suspendedOnList.remove(objectName);
  -            } // end of if ()
               
  -         } // end of while ()
  +            // destroy all the mbeans that depend on me
  +            destroy(((ServiceContext) iterator.next()).objectName);  
  +         }
            
  -      } // end of if ()
  +         // Call create on the service Proxy  
  +         try { ctx.proxy.destroy(); }
  +            
  +         catch (Exception e){ ctx.state = ServiceContext.FAILED; throw e;}
  +      
  +      
  +      }
  +   }   
  +   
  +   
  +   
  +   /**
  +   * #Description of the Method
  +   *
  +   * @param mbeanElement Description of Parameter
  +   * @exception Exception Description of Exception
  +   */
  +   public void remove(Element mbeanElement) throws Exception
  +   {
  +      
  +      remove(parseObjectName(mbeanElement));
  +   }
  +   
  +   
  +   /**
  +   * This MBean is going buh bye
  +   *
  +   * @param objectName Description of Parameter
  +   * @exception Exception Description of Exception
  +   */
  +   public void remove(ObjectName objectName) throws Exception
  +   {
         
  +      ServiceContext ctx = getServiceContext(objectName);    
         
  +      // Notify those that think I depend on them
  +      Iterator iterator = ctx.iDependOn.iterator();
  +      while (iterator.hasNext()) 
  +      {
  +         ((ServiceContext) iterator.next()).dependsOnMe.remove(ctx);
  +      }
  +      
         // Do we have a deployed MBean?
         if (server.isRegistered(objectName))
         {
            if (log.isDebugEnabled()) {
  -            log.debug("undeploying " + objectName + " from server");
  +            log.debug("removing " + objectName + " from server");
            }
            
  -         //Remove from local maps
  -         startedServices.remove(objectName);
  -         //Service service = (Service)nameToServiceMap.remove(objectName);
            nameToServiceMap.remove(objectName);
  -         // Remove the MBean from the MBeanServer
  -         server.unregisterMBean(objectName);
  -
  -         // Remove the MBeanClassLoader used by the MBean
  -         ObjectName loader =
  -            new ObjectName("ZClassLoaders:id=" + objectName.hashCode());
  -         if (server.isRegistered(loader)) 
  -         {
  -            server.unregisterMBean(loader);
  -         } // end of if ()
  +         
  +         // remove the mbean from the instaled ones
  +         installedServices.remove(ctx);
  +         
  +         creator.remove(objectName);
         }
         else 
         {
            if (log.isDebugEnabled()) {
  -            log.debug("no need to undeploy " + objectName + " from server");
  +            log.debug("no need to remove " + objectName + " from server");
            }
  -
  -      } // end of else
         
  +      } // end of else
  +   
      }
  -
  +   
      // MBeanRegistration implementation ----------------------------------------
  -
  +   
      /**
  -    * #Description of the Method
  -    *
  -    * @param server Description of Parameter
  -    * @param name Description of Parameter
  -    * @return Description of the Returned Value
  -    * @exception Exception Description of Exception
  -    */
  +   * #Description of the Method
  +   *
  +   * @param server Description of Parameter
  +   * @param name Description of Parameter
  +   * @return Description of the Returned Value
  +   * @exception Exception Description of Exception
  +   */
      public ObjectName preRegister(MBeanServer server, ObjectName name)
  -          throws Exception
  +   throws Exception
      {
         this.server = server;
  -
  +      
         creator = new ServiceCreator(server);
         configurator = new ServiceConfigurator(server);
  -
  +      
         log.info("Controller MBean online");
         return name == null ? new ObjectName(OBJECT_NAME) : name;
  +   
  +   
      }
  -
  +   
      public void postRegister(Boolean registrationDone)
      {
         if (!registrationDone.booleanValue())
  @@ -413,176 +511,66 @@
      }
      
      public void preDeregister()
  -      throws Exception
  +   throws Exception
      {
      }
      
      public void postDeregister()
      {
  -   }
  -
  -   // methods about suspension.
  -
  -   public synchronized boolean isSuspended(ObjectName objectName)
  -   {
  -      return suspendedToMissingMBeanMap.containsKey(objectName);
      }
  -
  +   
  +   
      // Service implementation ----------------------------------------
  -
  -
  +   
  +   
      /**
  -    * This is the only one we should have of these lifecycle methods!
  -    */
  +   * This is the only one we should have of these lifecycle methods!
  +   */
      public synchronized void shutdown()
      {
  -      log.info("Stopping " + startedServices.size() + " services");
  -
  -      List servicesCopy = new ArrayList(startedServices);
  -      //ListIterator enum = servicesCopy.listIterator();
  +      log.info("Stopping " + nameToServiceMap.size() + " services");
  +      
  +      
  +      List servicesCopy = new ArrayList(installedServices);
  +      
         int serviceCounter = 0;
         ObjectName name = null;
  -
  +      
         for (ListIterator i = servicesCopy.listIterator(servicesCopy.size() - 1);
  -           i.hasPrevious(); ) 
  +         i.hasPrevious(); ) 
         {
  -         name = (ObjectName)i.previous();
  -
  +         name = ((ServiceContext)i.previous()).objectName;
  +         
            try
            {
  -            undeploy(name);
  -            //((Service)nameToServiceMap.get(name)).stop();
  -            //((Service)nameToServiceMap.get(name)).destroy();//should be obsolete 
soon
  -            //server.unregisterMBean(name);
  +            remove(name);
               serviceCounter++;
            }
            catch (Throwable e)
            {
  -            log.error("Could not undeploy " + name, e);
  +            log.error("Could not remove " + name, e);
            }
         }
         log.info("Stopped " + serviceCounter + " services");
  -   }
  -
  -
  -
  -
  -   /**
  -    * #Description of the Method
  -    *
  -    * @param serviceName Description of Parameter
  -    * @exception Exception Description of Exception
  -    */
  -   public void start(ObjectName serviceName) throws Exception
  -   {
  -      if (suspendedToMissingMBeanMap.containsKey(serviceName)) 
  -      {
  -         log.debug("waiting to start " + serviceName + " until dependencies are 
resolved");
  -         return;     
  -      } // end of if ()
  -       
  -      if (nameToServiceMap.containsKey(serviceName))
  -      {
  -
  -         ((Service)nameToServiceMap.get(serviceName)).start();
  -         startedServices.add(serviceName);
  -      }
  -      else
  -      {
  -         throw new InstanceNotFoundException
  -            ("Could not find " + serviceName.toString());
  -      }
  -      ArrayList waitingList = 
(ArrayList)missingToSuspendedMBeanMap.remove(serviceName);
  -      if (waitingList != null) 
  -      {
  -         Iterator waiting = waitingList.iterator();
  -         while (waiting.hasNext()) 
  -         {
  -            ObjectName waitingName = (ObjectName)waiting.next();        
  -            //Is it waiting for anyone else?
  -            ArrayList waitingFor = 
(ArrayList)suspendedToMissingMBeanMap.get(waitingName);
  -            if (waitingFor == null) 
  -            {
  -               //maybe should be DeploymentException, but it might pull in too many 
classes.
  -               throw new Exception("Missing suspended to Missing map entry between 
suspended: " + waitingName + " and missing: " + serviceName);                    
  -            } // end of if ()
  -            waitingFor.remove(serviceName);
  -            if (waitingFor.size() == 0) 
  -            {
  -               //not waiting for anyone else, can finish deploying.
  -               log.debug("missing mbeans now present, finishing deployment of " + 
waitingName);
  -               suspendedToMissingMBeanMap.remove(waitingName);
  -               start(waitingName);
  -            } // end of if ()
  -            else 
  -            {
  -               log.debug("There are still missing mbeans, deployment of " + 
waitingName + " postponed");
  -
  -            } // end of else
  -            
  -         } // end of while ()
  -         
  -              
  -      } // end of if ()
  -      
  -   }
  -
  -   /**
  -    * #Description of the Method
  -    *
  -    * @param serviceName Description of Parameter
  -    * @exception Exception Description of Exception
  -    */
  -   public void stop(ObjectName serviceName) throws Exception
  -   {
  -      ArrayList usingList = (ArrayList)mbeanRefToMBeansMap.get(serviceName);
  -      if (usingList != null) 
  -      {
  -         //we have to stop these beans that depend on serviceName. 
  -         Iterator using = usingList.iterator();  
  -         while (using.hasNext()) 
  -         {
  -            ObjectName usingName = (ObjectName)using.next();
  -            log.debug("stopping object " + usingName + " using " + serviceName);
  -            if (!isWaitingFor(serviceName, usingName)) 
  -            {
  -               markWaiting(serviceName, usingName);
  -               stop(usingName);
  -            } // end of if ()
  -           
  -         } // end of while ()
  -         
  -      } // end of if ()
  -      
  -      if (nameToServiceMap.containsKey(serviceName))
  -      {
  -
  -         ((Service)nameToServiceMap.get(serviceName)).stop();
  -      }
  -      else
  -      {
  -         throw new InstanceNotFoundException
  -            ("Could not find " + serviceName.toString());
  -      }
      }
  -
  -
  +   
  +   
      /**
  -    * Get the Service interface through which the mbean given by objectName
  -    * will be managed.
  -    *
  -    * @param objectName
  -    * @param info
  -    * @param serviceFactory
  -    * @return The ServiceInstance value
  -    * 
  -    * @throws ClassNotFoundException
  -    * @throws InstantiationException
  -    * @throws IllegalAccessException
  -    */
  -   private Service getServiceInstance(ObjectName objectName,
  -                                      String serviceFactory)
  -       throws ClassNotFoundException, InstantiationException, 
IllegalAccessException, JMException//, InstanceNotFoundException, 
IntrospectionException
  +   * Get the Service interface through which the mbean given by objectName
  +   * will be managed.
  +   *
  +   * @param objectName
  +   * @param info
  +   * @param serviceFactory
  +   * @return The ServiceInstance value
  +   * 
  +   * @throws ClassNotFoundException
  +   * @throws InstantiationException
  +   * @throws IllegalAccessException
  +   */
  +   private Service getServiceProxy(ObjectName objectName,
  +      String serviceFactory)
  +   throws ClassNotFoundException, InstantiationException, IllegalAccessException, 
JMException//, InstanceNotFoundException, IntrospectionException
      {
         Service service = null;
         ClassLoader loader = Thread.currentThread().getContextClassLoader();
  @@ -600,40 +588,38 @@
            InvocationHandler handler = new ServiceProxy(objectName, opInfo);
            service = (Service)Proxy.newProxyInstance(loader, interfaces, handler);
         }
  -
  +      
         return service;
      }
  -
  -   // Protected -----------------------------------------------------
  -
  +   
      /**
  -    * Parse an object name from the given element attribute 'name'.
  -    *
  -    * @param element   Element to parse name from.
  -    * @return          Object name.
  -    * 
  -    * @throws ConfigurationException   Missing attribute 'name' (thrown if 
  -    *                                  'name' is null or "").
  -    * @throws MalformedObjectNameException
  -    */
  +   * Parse an object name from the given element attribute 'name'.
  +   *
  +   * @param element   Element to parse name from.
  +   * @return          Object name.
  +   * 
  +   * @throws ConfigurationException   Missing attribute 'name' (thrown if 
  +   *                                  'name' is null or "").
  +   * @throws MalformedObjectNameException
  +   */
      private ObjectName parseObjectName(final Element element)
  -          throws ConfigurationException, MalformedObjectNameException
  +   throws ConfigurationException, MalformedObjectNameException
      {
         String name = element.getAttribute("name");
         if (name == null || name.trim().equals(""))
         {
            throw new ConfigurationException
  -               ("MBean attribute 'name' must be given.");
  +         ("MBean attribute 'name' must be given.");
         }
         return new ObjectName(name);
      }
  -
  +   
      /**
  -    * Go through the myriad of nested JMX exception to pull out the true
  -    * exception if possible and log it.
  -    *
  -    * @param e The exception to be logged.
  -    */
  +   * Go through the myriad of nested JMX exception to pull out the true
  +   * exception if possible and log it.
  +   *
  +   * @param e The exception to be logged.
  +   */
      private void logException(String message, Throwable e)
      {
         if (e instanceof RuntimeErrorException)
  @@ -658,72 +644,61 @@
         }
         log.error(message, e);
      }
  -
  -   private void markWaiting(ObjectName missing, ObjectName waiting)
  -   {
  -      ArrayList waitingList = (ArrayList)missingToSuspendedMBeanMap.get(missing);
  -      if (waitingList == null) 
  -      {
  -         waitingList = new ArrayList();
  -         missingToSuspendedMBeanMap.put(missing, waitingList);
  -      } // end of if ()
  -      if (!waitingList.contains(waiting)) 
  -      {
  -         waitingList.add(waiting);        
  -      } // end of if ()          
  -      //Now do the other way.         
  -      ArrayList missingList = (ArrayList)suspendedToMissingMBeanMap.get(waiting);
  -      if (missingList == null) 
  -      {
  -         missingList = new ArrayList();
  -         suspendedToMissingMBeanMap.put(waiting, missingList);
  -      } // end of if ()
  -      if (!missingList.contains(missing)) 
  -      {
  -         missingList.add(missing);        
  -      } // end of if ()                   
  -   }
  -
  -   private boolean isWaitingFor(ObjectName serviceName, ObjectName usingName)
  +   
  +   // Inner classes -------------------------------------------------
  +   
  +   // Create a Service Context for the service, or get one if it exists
  +   public synchronized ServiceContext getServiceContext(ObjectName objectName)
      {
  -      ArrayList waitingList = 
(ArrayList)missingToSuspendedMBeanMap.get(serviceName);
  -      if (waitingList == null) 
  -      {
  -         return false;//noone is waiting for this guy.        
  -      } // end of if ()
  -      return waitingList.contains(usingName);
  +      // If it is already there just return it
  +      if (nameToServiceMap.containsKey(objectName)) return (ServiceContext) 
nameToServiceMap.get(objectName);
  +         
  +      // If not create it, add it and return it
  +      ServiceContext ctx = new ServiceContext();
  +      ctx.objectName = objectName;
  +      
  +      // we keep track of these here
  +      nameToServiceMap.put(objectName, ctx);
  +      
  +      return ctx;
      }
  -
  -   // Inner classes -------------------------------------------------
  -
  +   
  +   
  +   
      /**
  -    * An implementation of InvocationHandler used to proxy of the Service
  -    * interface for mbeans. It determines which of the start/stop
  -    * methods of the Service interface an mbean implements by inspecting its
  -    * MBeanOperationInfo values. Each Service interface method that has a
  -    * matching operation is forwarded to the mbean by invoking the method
  -    * through the MBeanServer object.
  -    */
  -   private class ServiceProxy
  -      implements InvocationHandler
  +   * A mapping from the Service interface method names to the corresponding
  +   * index into the ServiceProxy.hasOp array.
  +   */
  +   private static HashMap serviceOpMap = new HashMap();
  +   
  +   /**
  +   * An implementation of InvocationHandler used to proxy of the Service
  +   * interface for mbeans. It determines which of the start/stop
  +   * methods of the Service interface an mbean implements by inspecting its
  +   * MBeanOperationInfo values. Each Service interface method that has a
  +   * matching operation is forwarded to the mbean by invoking the method
  +   * through the MBeanServer object.
  +   */
  +   public class ServiceProxy
  +   implements InvocationHandler
      {
         private boolean[] hasOp = { false, false, false, false };
         private ObjectName objectName;
  -
  +      
         /**
  -       * Go through the opInfo array and for each operation that matches on of
  -       * the Service interface methods set the corresponding hasOp array value
  -       * to true.
  -       *
  -       * @param objectName
  -       * @param opInfo
  -       */
  +      * Go through the opInfo array and for each operation that matches on of
  +      * the Service interface methods set the corresponding hasOp array value
  +      * to true.
  +      *
  +      * @param objectName
  +      * @param opInfo
  +      */
         public ServiceProxy(ObjectName objectName,
  -                          MBeanOperationInfo[] opInfo)
  +         MBeanOperationInfo[] opInfo)
         {
            this.objectName = objectName;
            int opCount = 0;
  -
  +         
            for (int op = 0; op < opInfo.length; op++)
            {
               MBeanOperationInfo info = opInfo[op];
  @@ -733,7 +708,7 @@
               {
                  continue;
               }
  -
  +            
               // Validate that is a no-arg void return type method
               if (info.getReturnType().equals("void") == false)
               {
  @@ -743,37 +718,37 @@
               {
                  continue;
               }
  -
  +            
               hasOp[opID.intValue()] = true;
               opCount++;
            }
  -
  +         
            // Log a warning if the mbean does not implement
            // any Service methods
            if (opCount == 0)
            {
               log.warn(objectName +
  -                  " does not implement any Service methods");
  +               " does not implement any Service methods");
            }
         }
  -
  +      
         /**
  -       * Map the method name to a Service interface method index and if the
  -       * corresponding hasOp array element is true, dispatch the method to the
  -       * mbean we are proxying.
  -       *
  -       * @param proxy
  -       * @param method
  -       * @param args
  -       * @return             Always null.
  -       * @throws Throwable
  -       */
  +      * Map the method name to a Service interface method index and if the
  +      * corresponding hasOp array element is true, dispatch the method to the
  +      * mbean we are proxying.
  +      *
  +      * @param proxy
  +      * @param method
  +      * @param args
  +      * @return             Always null.
  +      * @throws Throwable
  +      */
         public Object invoke(Object proxy, Method method, Object[] args)
  -             throws Throwable
  +      throws Throwable
         {
            String name = method.getName();
            Integer opID = (Integer)serviceOpMap.get(name);
  -
  +         
            if (opID != null && hasOp[opID.intValue()] == true)
            {
               try
  @@ -784,29 +759,30 @@
               catch (JMRuntimeException e)
               {
                  logException("JMRuntimeException thrown during ServiceProxy 
operation " +
  -                            name + " on mbean " + objectName, e);
  +                  name + " on mbean " + objectName, e);
                  throw e;
               }
               catch (JMException e)
               {
                  logException("JMException thrown during ServiceProxy operation " +
  -                            name + " on mbean " + objectName, e);
  +                  name + " on mbean " + objectName, e);
                  throw e;
               }
            }
  -
  +         
            return null;
         }
      }
  -
  +   
      /**
  -    * Initialize the service operation map.
  -    */
  +   * Initialize the service operation map.
  +   */
      static
      {
  -      //serviceOpMap.put("init", new Integer(0));
  +      serviceOpMap.put("create", new Integer(0));
         serviceOpMap.put("start", new Integer(1));
  -      //serviceOpMap.put("destroy", new Integer(2));
  +      
  +      serviceOpMap.put("destroy", new Integer(2));
         serviceOpMap.put("stop", new Integer(3));
      }
   }
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to