Package org.jboss.ha.framework.server

Source Code of org.jboss.ha.framework.server.HAServiceImpl$RpcHandler

/*
* 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.ha.framework.server;

import java.io.Serializable;
import java.util.EventObject;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.jboss.ha.framework.interfaces.DistributedReplicantManager;
import org.jboss.ha.framework.interfaces.EventListener;
import org.jboss.ha.framework.interfaces.GroupRpcDispatcher;
import org.jboss.ha.framework.interfaces.HAPartition;
import org.jboss.ha.framework.interfaces.HAService;
import org.jboss.logging.Logger;

/**
* Base class for clustered services.
* Provides clustered event facility.
*
* @param <E> type of event generated by this service
* @author Paul Ferraro
*/
public class HAServiceImpl<E extends EventObject> implements HAService<E>, EventFacility<E>, DistributedReplicantManager.ReplicantListener
{
   private static final Class<?>[] HANDLE_EVENT_TYPES = new Class[] { EventObject.class };
   private static final String REPLICANT_TOKEN = "";
  
   protected final Logger log = Logger.getLogger(this.getClass());
  
   private final HAServiceRpcHandler<E> rpcHandler = new RpcHandler();
   private final EventFacility<E> eventFacility;
   private final EventFactory<E> eventFactory;
   private final List<EventListener<E>> eventListeners = new CopyOnWriteArrayList<EventListener<E>>();
  
   private volatile HAPartition partition;
   private volatile String name;
   private volatile boolean registerClassLoader = false;
  
   public HAServiceImpl(EventFactory<E> eventFactory, EventFacility<E> eventFacility)
   {
      this.eventFactory = eventFactory;
      this.eventFacility = eventFacility;
   }
  
   public HAServiceImpl(EventFactory<E> eventFactory)
   {
      this.eventFactory = eventFactory;     
      this.eventFacility = this;
   }
  
   public void addEventListener(EventListener<E> listener)
   {
      this.eventListeners.add(listener);
   }
  
   public void removeEventListener(EventListener<E> listener)
   {
      this.eventListeners.remove(listener);
   }
  
   /**
    * @see org.jboss.ha.framework.server.EventFacility#notifyListeners(java.util.EventObject)
    */
   @Override
   public void notifyListeners(E event)
   {
      for (EventListener<E> listener: this.eventListeners)
      {
         try
         {
            listener.handleEvent(event);
         }
         catch (Exception e)
         {
            this.log.warn(e.getMessage(), e);
         }
      }
   }
  
   /**
    * @see org.jboss.ha.framework.interfaces.HAService#getHAPartition()
    */
   @Override
   public HAPartition getHAPartition()
   {
      return this.partition;
   }

   /**
    * @see org.jboss.ha.framework.interfaces.HAService#setHAPartition(org.jboss.ha.framework.interfaces.HAPartition)
    */
   @Override
   public void setHAPartition(HAPartition partition)
   {
      this.partition = partition;
   }
  
   /**
    * @see org.jboss.ha.framework.interfaces.HAService#isRegisterThreadContextClassLoader()
    */
   @Override
   public boolean isRegisterThreadContextClassLoader()
   {
      return this.registerClassLoader;
   }

   /**
    * @see org.jboss.ha.framework.interfaces.HAService#setRegisterThreadContextClassLoader(boolean)
    */
   @Override
   public void setRegisterThreadContextClassLoader(boolean registerClassLoader)
   {
      this.registerClassLoader = registerClassLoader;
   }
  
   @Override
   public String getServiceHAName()
   {
      return this.name;
   }
  
   /**
    * @see org.jboss.ha.framework.interfaces.HAService#setServiceHAName(java.lang.String)
    */
   @Override
   public void setServiceHAName(String name)
   {
      this.name = name;
   }
  
   /**
    * @see org.jboss.ha.framework.interfaces.EventListener#handleEvent(java.util.EventObject)
    */
   @Override
   public void handleEvent(E event) throws Exception
   {
      this.callAsyncMethodOnPartition("handleEvent", new Object[] { event }, HANDLE_EVENT_TYPES);
   }

   protected HAServiceRpcHandler<E> getRpcHandler()
   {
      return this.rpcHandler;
   }
  
   protected EventFactory<E> getEventFactory()
   {
      return this.eventFactory;
   }
  
   protected EventFacility<E> getEventFacility()
   {
      return this.eventFacility;
   }

   /**
    * @see org.jboss.ha.framework.interfaces.HAService#create()
    */
   @Override
   public void create() throws Exception
   {
   }
  
   /**
    * @see org.jboss.ha.framework.interfaces.HAService#start()
    */
   @Override
   public void start() throws Exception
   {
      this.registerRPCHandler();

      this.registerDRMListener();
   }

   /**
    * @see org.jboss.ha.framework.interfaces.HAService#stop()
    */
   @Override
   public void stop()
   {
      try
      {
         this.unregisterDRMListener();
  
         this.unregisterRPCHandler();
      }
      catch (Exception e)
      {
         this.log.error("Failed to stop service.", e);
      }
   }

   /**
    * @see org.jboss.ha.framework.interfaces.HAService#destroy()
    */
   @Override
   public void destroy()
   {
   }

   @SuppressWarnings("unchecked")
   protected <T> List<T> callMethodOnPartition(String methodName, Object[] args, Class<?>[] types) throws Exception
   {
      GroupRpcDispatcher dispatcher = this.partition;
      return (List<T>) dispatcher.callMethodOnCluster(this.name, methodName, args, types, true);
   }

   protected void callAsyncMethodOnPartition(String methodName, Object[] args, Class<?>[] types) throws Exception
   {
      this.partition.callAsynchMethodOnCluster(this.name, methodName, args, types, true);
   }
  
   protected void registerRPCHandler()
   {
      String key = this.getHAServiceKey();
     
      if (this.isRegisterThreadContextClassLoader())
      {
         this.partition.registerRPCHandler(key, this.getRpcHandler(), Thread.currentThread().getContextClassLoader());
      }
      else
      {
         this.partition.registerRPCHandler(key, this.getRpcHandler());
      }
   }

   protected void unregisterRPCHandler()
   {
      this.partition.unregisterRPCHandler(this.getHAServiceKey(), this.getRpcHandler());
   }
  
   protected void registerDRMListener() throws Exception
   {
      if (log.isDebugEnabled())
      {
         log.debug("HAServiceImpl.registerDRMListener for service=" + getHAServiceKey());  
      }

      DistributedReplicantManager drm = this.partition.getDistributedReplicantManager();
     
      String key = this.getHAServiceKey();
     
      drm.registerListener(key, this);

      // this ensures that the DRM knows that this node has the MBean deployed
      drm.add(key, this.getReplicant());
   }
  
   protected void unregisterDRMListener() throws Exception
   {
      DistributedReplicantManager drm = this.partition.getDistributedReplicantManager();

      String key = this.getHAServiceKey();
     
      // remove replicant node
      drm.remove(key);
    
      // unregister
      drm.unregisterListener(key, this);
   }

   /**
    * {@inheritDoc}
    * @return the key used by the DRM and partition rpc handler mapping.
    */
   @Override
   public String getHAServiceKey()
   {
      return this.name;
   }
  
   /**
    * @return the object to be registered with the {@link org.jboss.ha.framework.interfaces.DistributedReplicantManager}.
    */
   protected Serializable getReplicant()
   {
      return REPLICANT_TOKEN;
   }

   /**
    * @see org.jboss.ha.framework.interfaces.DistributedReplicantManager.ReplicantListener#replicantsChanged(java.lang.String, java.util.List, int, boolean)
    */
   @Override
   public void replicantsChanged(String key, List<?> newReplicants, int newReplicantsViewId, boolean merge)
   {
      if (key.equals(this.getHAServiceKey()))
      {
         // This synchronized block was added when the internal behavior of
         // DistributedReplicantManagerImpl was changed so that concurrent
         // replicantsChanged notifications are possible. Synchronization
         // ensures that this change won't break non-thread-safe
         // subclasses of HAServiceMBeanSupport.
         synchronized (this)
         {
            // change in the topology callback
            this.partitionTopologyChanged(newReplicants, newReplicantsViewId, merge);
         }
      }
   }
  
   protected void partitionTopologyChanged(List<?> newReplicants, int newReplicantsViewId, boolean merge)
   {
      this.log.debug("partitionTopologyChanged(). cluster view id: " + newReplicantsViewId);
   }
  
   protected class RpcHandler implements HAServiceRpcHandler<E>
   {
      /**
       * @see org.jboss.ha.framework.interfaces.HAService.RpcHandler#handleNotification(java.lang.Object)
       */
      @Override
      public void handleEvent(E event) throws Exception
      {
         HAServiceImpl.this.getEventFacility().notifyListeners(event);
      }     
   }
}
TOP

Related Classes of org.jboss.ha.framework.server.HAServiceImpl$RpcHandler

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.