Package org.jboss.proxy.generic

Source Code of org.jboss.proxy.generic.ProxyFactoryHA$StateChangeListener

/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.proxy.generic;

import java.util.List;

import javax.management.AttributeChangeNotificationFilter;
import javax.management.NotificationListener;
import javax.management.AttributeChangeNotification;
import javax.management.Notification;

import org.jboss.invocation.Invoker;
import org.jboss.invocation.InvokerHA;
import org.jboss.invocation.InvokerProxyHA;
import org.jboss.invocation.jrmp.server.JRMPProxyFactory;
import org.jboss.ha.framework.interfaces.LoadBalancePolicy;
import org.jboss.ha.framework.interfaces.DistributedReplicantManager;
import org.jboss.ha.framework.interfaces.HAPartition;
import org.jboss.ha.framework.interfaces.RoundRobin;
import org.jboss.ha.framework.server.HATarget;
import org.jboss.proxy.GenericProxyFactory;
import org.jboss.system.Registry;
import org.jboss.system.ServiceMBean;

/**
* ProxyFactory for Clustering
*
@author <a href="mailto:adrian@jboss.org">Adrian Brock</a>
@version $Revision: 105943 $
*/
public class ProxyFactoryHA
   extends JRMPProxyFactory
   implements ProxyFactoryHAMBean, DistributedReplicantManager.ReplicantListener
{
   protected String replicantName = null;  
   protected InvokerHA invokerHA;
   protected HATarget target;
   protected Invoker invoker;
   protected DistributedReplicantManager drm = null;
   protected HAPartition partition;
   protected String loadBalancePolicy = RoundRobin.class.getName();
   protected NotificationListener listener;
   protected int state = 0;

   public HAPartition getPartition()
   {
      return partition;
   }

   public void setPartition(HAPartition partition)
   {
      this.partition = partition;
   }
  
   public String getLoadBalancePolicy()
   {
      return loadBalancePolicy;
   }

   public void setLoadBalancePolicy(String loadBalancePolicy)
   {
      this.loadBalancePolicy = loadBalancePolicy;
   }

   public void createService() throws Exception
   {
      super.createService();
     
      // we register our inner-class to retrieve STATE notifications from our container
      AttributeChangeNotificationFilter filter = new AttributeChangeNotificationFilter();
      filter.enableAttribute("State");
      listener = new StateChangeListener();
      getServer().addNotificationListener(getTargetName(), listener, filter, null);
   }
  
   protected void startService() throws Exception
   {
      String partitionName = partition.getPartitionName();
      this.drm = partition.getDistributedReplicantManager();
     
      replicantName = getTargetName().toString();
     
      invokerHA = (InvokerHA) Registry.lookup(getInvokerName());
      if (invokerHA == null)
         throw new RuntimeException("Invoker is not registered: " + getInvokerName());

      int mode = HATarget.MAKE_INVOCATIONS_WAIT;
      if (state == ServiceMBean.STARTED)
         mode = HATarget.ENABLE_INVOCATIONS;
      target = new HATarget(partition, replicantName, invokerHA.getStub(), mode);
      invokerHA.registerBean(getServiceName(), target);

      String clusterFamilyName = partitionName + "/" + getTargetName() + "/";
     
      // make ABSOLUTLY sure we do register with the DRM AFTER the HATarget
      // otherwise we will refresh the *old* home in JNDI (ie before the proxy
      // is re-generated)
      drm.registerListener (replicantName, this);
     
      ClassLoader cl = Thread.currentThread().getContextClassLoader();
      Class<?> clazz;
      LoadBalancePolicy policy;
     
      clazz = cl.loadClass(loadBalancePolicy);
      policy = (LoadBalancePolicy)clazz.newInstance();
      invoker = invokerHA.createProxy(getServiceName(), policy, clusterFamilyName + "H");
     
      super.startService();
   }
  
   public void stopService() throws Exception
   {
      super.stopService();

      // JBAS-5164.  Unregister the listener first, or when we destroy
      // the target we will get a callback and rebind the proxy
      if (drm != null)
         drm.unregisterListener(replicantName, this);
     
      try
      {
         invokerHA.unregisterBean(getServiceName());
         target.destroy();
      }
      catch (Exception ignored)
      {
         // ignore.
      }
   }

   protected void destroyService() throws Exception
   {
      super.destroyService();
      getServer().removeNotificationListener(getTargetName(), listener);
   }

   protected void containerIsFullyStarted ()
   {
      if (target != null)
         target.setInvocationsAuthorization(HATarget.ENABLE_INVOCATIONS);
   }
  
   protected void containerIsAboutToStop()
   {
      if (target != null)
      {
         target.setInvocationsAuthorization(HATarget.DISABLE_INVOCATIONS);
         target.disable();
      }
   }

   // synchronized keyword added when it became possible for DRM to issue
   // concurrent replicantsChanged notifications. JBAS-2169.
   public synchronized void replicantsChanged(String key,
                                              List<?> newReplicants,
                                              int newReplicantsViewId,
                                              boolean merge)
   {
      try
      {
         if (invoker instanceof InvokerProxyHA)
            ((InvokerProxyHA) invoker).updateClusterInfo(target.getReplicantList(), target.getCurrentViewId());

         log.debug ("Rebinding in JNDI... " + key);
         rebind();
      }
      catch (Exception none)
      {
         log.debug(none);
      }
   }

   protected void createProxy
   (
      Object cacheID,
      String proxyBindingName,
      ClassLoader loader,
      Class[] ifaces
   )
   {
      GenericProxyFactory proxyFactory = new GenericProxyFactory();
      theProxy = proxyFactory.createProxy(cacheID, getServiceName(), invoker,
         getJndiName(), proxyBindingName, getInterceptorClasses(), loader, ifaces);
   }

   // inner-classes
  
   class StateChangeListener implements NotificationListener
   {
      public void handleNotification (Notification notification, Object handback)
      {
         if (notification instanceof AttributeChangeNotification)
         {
            AttributeChangeNotification notif = (AttributeChangeNotification) notification;
            state = ((Integer)notif.getNewValue()).intValue();
           
            if (state == ServiceMBean.STARTED)
            {
               log.debug ("Started: enabling remote access to mbean " + getTargetName());
               containerIsFullyStarted ();
            }
            else if (state == ServiceMBean.STOPPING)
            {
               log.debug ("About to stop: disabling remote access to mbean " + getTargetName());
               containerIsAboutToStop ();
            }
         }
      }
     
   }
}
TOP

Related Classes of org.jboss.proxy.generic.ProxyFactoryHA$StateChangeListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.