Package org.jboss.cache.invocation

Source Code of org.jboss.cache.invocation.RemoteCacheInvocationDelegate

package org.jboss.cache.invocation;

import org.apache.commons.logging.LogFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.buddyreplication.BuddyGroup;
import org.jboss.cache.buddyreplication.BuddyManager;
import org.jboss.cache.buddyreplication.BuddyNotInitException;
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.marshall.MethodCall;
import org.jboss.cache.marshall.MethodCallFactory;
import org.jboss.cache.marshall.MethodDeclarations;
import org.jgroups.Address;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
* A sublcass of CacheInvocationDelegate, used by remote instances to invoke methods on current cache.
*
* @author Manik Surtani (<a href="mailto:manik@jboss.org">manik@jboss.org</a>)
* @since 2.1.0
*/
public class RemoteCacheInvocationDelegate extends CacheInvocationDelegate
{
   private BuddyManager buddyManager;

   public RemoteCacheInvocationDelegate()
   {
      originLocal = false;
      log = LogFactory.getLog(RemoteCacheInvocationDelegate.class);
   }

   @Inject
   private void injectBuddyManager(BuddyManager buddyManager)
   {
      this.buddyManager = buddyManager;
   }

   // ------------- start: buddy replication specific 'lifecycle' method calls

   public void assignToBuddyGroup(BuddyGroup group, Map<Fqn, byte[]> state) throws Exception
   {
      if (buddyManager != null)
         buddyManager.handleAssignToBuddyGroup(group, state);
      else if (log.isWarnEnabled())
         log.warn("Received assignToBuddyGroup call from group owner [" + group.getDataOwner() + "] but buddy replication is not enabled on this node!");
   }

   public void removeFromBuddyGroup(String groupName) throws BuddyNotInitException
   {
      if (buddyManager != null)
         buddyManager.handleRemoveFromBuddyGroup(groupName);
      else if (log.isWarnEnabled())
         log.warn("Received removeFromBuddyGroup call for group name [" + groupName + "] but buddy replication is not enabled on this node!");

   }

   public void announceBuddyPoolName(Address address, String buddyPoolName)
   {
      if (buddyManager != null)
         buddyManager.handlePoolNameBroadcast(address, buddyPoolName);
      else if (log.isWarnEnabled())
         log.warn("Received annouceBuddyPoolName call from [" + address + "] but buddy replication is not enabled on this node!");
   }

   public void dataGravitationCleanup(Fqn primary, Fqn backup) throws Exception
   {
//      MethodCall primaryDataCleanup, backupDataCleanup;
      if (buddyManager.isDataGravitationRemoveOnFind())
      {
         if (log.isTraceEnabled())
            log.trace("DataGravitationCleanup: Removing primary (" + primary + ") and backup (" + backup + ")");

         getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
         if (!removeNode(primary))
         {
            // only attempt to clean up the backup if the primary did not exist - a waste of a call otherwise.
            getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
            removeNode(backup);
         }
      }
      else
      {
         if (log.isTraceEnabled())
            log.trace("DataGravitationCleanup: Evicting primary (" + primary + ") and backup (" + backup + ")");
         //primaryDataCleanup = MethodCallFactory.create(MethodDeclarations.evictNodeMethodLocal, primary);
         evict(primary, true);
         //backupDataCleanup = MethodCallFactory.create(MethodDeclarations.evictNodeMethodLocal, backup);
         evict(backup, true);
      }
   }

   // ------------- end: buddy replication specific 'lifecycle' method calls


   public Object _replicate(MethodCall methodCall) throws Throwable
   {
      try
      {
         Object retVal = invoke(methodCall);
         // we only need to return values for a set of remote calls; not every call.
         if (MethodDeclarations.returnValueForRemoteCall(methodCall.getMethodId()))
         {
            return retVal;
         }
         else
         {
            return null;
         }
      }
      catch (Throwable ex)
      {
         if (methodCall.getMethodId() != MethodDeclarations.putForExternalReadMethodLocal_id
               || methodCall.getMethodId() != MethodDeclarations.putForExternalReadVersionedMethodLocal_id)
         {
            if (!MethodDeclarations.isBuddyGroupOrganisationMethod(methodCall.getMethodId()) && log.isWarnEnabled())
               log.warn("replication failure with methodCall " + methodCall + " exception", ex);
            throw ex;
         }
         else return null;
      }
   }

   /**
    * Replicates a list of method calls.
    */
   public void _replicate(List<MethodCall> methodCalls) throws Throwable
   {
      for (MethodCall methodCall : methodCalls) _replicate((MethodCall) methodCall.getArgs()[0]);
   }

   public void block()
   {
      MethodCall m = MethodCallFactory.create(MethodDeclarations.blockChannelMethodLocal_id);
      invoke(m, true);
   }

   public void unblock()
   {
      MethodCall m = MethodCallFactory.create(MethodDeclarations.unblockChannelMethodLocal_id);
      invoke(m, true);
   }

   /**
    * A 'clustered get' call, called from a remote ClusteredCacheLoader.
    *
    * @return a List containing 2 elements: (true or false) and a value (Object).  If buddy replication
    *         is used one further element is added - an Fqn of the backup subtree in which this node may be found.
    */
   public List clusteredGet(MethodCall methodCall, Boolean searchBackupSubtrees)
   {
      if (log.isTraceEnabled())
         log.trace("Clustered Get called with params: " + methodCall + ", " + searchBackupSubtrees);
      Method m = methodCall.getMethod();
      Object[] args = methodCall.getArgs();

      Object callResults = null;

      try
      {
         Fqn fqn = (Fqn) args[0];

         if (log.isTraceEnabled()) log.trace("Clustered get: invoking call " + m + " with Fqn " + fqn);
         callResults = m.invoke(cache, args);
         boolean found = validResult(callResults, methodCall, fqn);
         if (log.isTraceEnabled()) log.trace("Got result " + callResults + ", found=" + found);
         if (found && callResults == null) callResults = createEmptyResults(methodCall);
      }
      catch (Exception e)
      {
         log.warn("Problems processing clusteredGet call", e);
      }

      List<Object> results = new ArrayList<Object>(2);
      if (callResults != null)
      {
         results.add(true);
         results.add(callResults);
      }
      else
      {
         results.add(false);
         results.add(null);
      }
      return results;
   }

   /**
    * Returns true if the call results returned a valid result.
    */
   private boolean validResult(Object callResults, MethodCall mc, Fqn fqn)
   {
      switch (mc.getMethodId())
      {
         case MethodDeclarations.getDataMapMethodLocal_id:
         case MethodDeclarations.getChildrenNamesMethodLocal_id:
            return callResults != null || exists(fqn);
         case MethodDeclarations.existsMethod_id:
            return (Boolean) callResults;
         default:
            return false;
      }
   }

   /**
    * Creates an empty Collection class based on the return type of the method called.
    */
   private Object createEmptyResults(MethodCall mc)
   {
      switch (mc.getMethodId())
      {
         case MethodDeclarations.getDataMapMethodLocal_id:
         case MethodDeclarations.getChildrenNamesMethodLocal_id:
            return Collections.emptyMap();
         default:
            return null;
      }
   }


}
TOP

Related Classes of org.jboss.cache.invocation.RemoteCacheInvocationDelegate

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.