FileDocCategorySizeDatePackage
UnifiedInvokerHA.javaAPI DocJBoss 4.2.16957Fri Jul 13 20:52:40 BST 2007org.jboss.invocation.unified.server

UnifiedInvokerHA

public class UnifiedInvokerHA extends UnifiedInvoker implements org.jboss.invocation.InvokerHA
author
Tom Elrod

Fields Summary
private HashMap
beanMap
Constructors Summary
public UnifiedInvokerHA()


    
   
      super();
      setSubSystem("invokerha");
   
Methods Summary
public org.jboss.invocation.InvokercreateProxy(javax.management.ObjectName beanName, org.jboss.ha.framework.interfaces.LoadBalancePolicy policy, java.lang.String proxyFamilyName)

      Integer hash = new Integer(beanName.hashCode());
      HATarget target = (HATarget) beanMap.get(hash);
      if(target == null)
      {
         throw new IllegalStateException("The bean hashCode not found");
      }

      String familyName = proxyFamilyName;
      if(familyName == null)
      {
         familyName = target.getAssociatedPartition().getPartitionName() + "/" + beanName;
      }

      UnifiedInvokerHAProxy proxy = new UnifiedInvokerHAProxy(getInvoker().getLocator(), getStrictRMIException(),
                                                              target.getReplicants(),
                                                              policy, proxyFamilyName, target.getCurrentViewId());
      return proxy;

   
public java.io.SerializablegetStub()

      return getInvoker().getLocator();
   
public java.lang.Objectinvoke(org.jboss.remoting.InvocationRequest invocationReq)
Implementation of the server invoker handler interface. Will take the invocation request and invoke down the interceptor chain.

param
invocationReq
return
throws
Throwable

      Invocation invocation = (Invocation) invocationReq.getParameter();
      Thread currentThread = Thread.currentThread();
      ClassLoader oldCl = currentThread.getContextClassLoader();
      ObjectName mbean = null;
      try
      {
         mbean = (ObjectName) Registry.lookup(invocation.getObjectName());

         /** Clustering **/
         long clientViewId = ((Long) invocation.getValue("CLUSTER_VIEW_ID")).longValue();
         HATarget target = (HATarget) beanMap.get(invocation.getObjectName());
         if(target == null)
         {
            // We could throw IllegalStateException but we have a race condition that could occur:
            // when we undeploy a bean, the cluster takes some time to converge
            // and to recalculate a new viewId and list of replicant for each HATarget.
            // Consequently, a client could own an up-to-date list of the replicants
            // (before the cluster has converged) and try to perform an invocation
            // on this node where the HATarget no more exist, thus receiving a
            // wrong exception and no failover is performed with an IllegalStateException
            //
            throw new GenericClusteringException(GenericClusteringException.COMPLETED_NO,
                                                 "target is not/no more registered on this node");
         }

         if(!target.invocationsAllowed())
         {
            throw new GenericClusteringException(GenericClusteringException.COMPLETED_NO,
                                                 "invocations are currently not allowed on this target");
         }
         /** End Clustering **/

         // The cl on the thread should be set in another interceptor
         Object obj = getServer().invoke(mbean,
                                         "invoke",
                                         new Object[]{invocation},
                                         Invocation.INVOKE_SIGNATURE);

         /** Clustering **/

         HARMIResponse haResponse = new HARMIResponse();

         if(clientViewId != target.getCurrentViewId())
         {
            haResponse.newReplicants = new ArrayList(target.getReplicants());
            haResponse.currentViewId = target.getCurrentViewId();
         }
         haResponse.response = obj;

         /** End Clustering **/

         return SerializationStreamFactory.getManagerInstance(getInvoker().getLocator().findSerializationType()).createdMarshalledValue(haResponse);
      }
      catch(Exception e)
      {
         Throwable th = JMXExceptionDecoder.decode(e);
         if(log.isTraceEnabled())
         {
            log.trace("Failed to invoke on mbean: " + mbean, th);
         }

         if(th instanceof Exception)
         {
            e = (Exception) th;
         }

         throw e;
      }
      finally
      {
         currentThread.setContextClassLoader(oldCl);
         Thread.interrupted(); // clear interruption because this thread may be pooled.
      }

   
protected voidjmxBind()

      Registry.bind(getServiceName(), this);
   
public voidregisterBean(javax.management.ObjectName beanName, org.jboss.ha.framework.server.HATarget target)

      Integer hash = new Integer(beanName.hashCode());

      if(beanMap.containsKey(hash))
      {
         throw new IllegalStateException("Trying to register bean (" + beanName + ") with an hash code that already exists");
      }
      beanMap.put(hash, target);
   
public voidunregisterBean(javax.management.ObjectName beanName)

      Integer hash = new Integer(beanName.hashCode());
      beanMap.remove(hash);