Package org.jboss.test.thirdparty.remoting.util

Source Code of org.jboss.test.thirdparty.remoting.util.RemotingTestSubsystem

/**
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.test.thirdparty.remoting.util;

import org.jboss.remoting.ServerInvocationHandler;
import org.jboss.remoting.ServerInvoker;
import org.jboss.remoting.InvocationRequest;
import org.jboss.remoting.callback.InvokerCallbackHandler;
import org.jboss.remoting.callback.Callback;
import org.jboss.remoting.callback.ServerInvokerCallbackHandler;
import org.jboss.test.thirdparty.remoting.SocketTransportCausalityTest;
import org.jboss.logging.Logger;

import javax.management.MBeanServer;
import java.io.Serializable;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

import EDU.oswego.cs.dl.util.concurrent.LinkedQueue;
import EDU.oswego.cs.dl.util.concurrent.Channel;

/**
* @author <a href="mailto:ovidiu@jboss.org">Ovidiu Feodorov</a>
* @version <tt>$Revision: 2098 $</tt>
*
* $Id: RemotingTestSubsystem.java 2098 2007-01-30 07:21:00Z ovidiu.feodorov@jboss.com $
*/
public class RemotingTestSubsystem
   implements TestableSubsystem, ServerInvocationHandler, Serializable
{
   // Constants ------------------------------------------------------------------------------------

   private static final long serialVersionUID = 5457454557215715L;

   private static final Logger log = Logger.getLogger(RemotingTestSubsystem.class);

   // Static ---------------------------------------------------------------------------------------

   /**
    * Very quick and dirty method. Don't try it at home. Needed it because some InvocationRequests
    * (even if the class is declared Serializable) contain request and response payloads which are
    * not, so I am having trouble sending them over wire back to the client.
    */
   private static InvocationRequest dirtyCopy(InvocationRequest source)
   {
      return new InvocationRequest(source.getSessionId(),
                                   source.getSubsystem(),
                                   source.getParameter(),
                                   null,
                                   null,
                                   source.getLocator());
   }

   // Attributes -----------------------------------------------------------------------------------

   private Channel invocationHistory;
   private List callbackListeners;

   private int[] counters = new int[10];

   private boolean failed;

   // Constructors ---------------------------------------------------------------------------------

   public RemotingTestSubsystem()
   {
      invocationHistory = new LinkedQueue();
      callbackListeners = new ArrayList();
   }

   // ServerInvocationHandler implementation -------------------------------------------------------

   public void setMBeanServer(MBeanServer server)
   {
   }

   public void setInvoker(ServerInvoker invoker)
   {
   }

   public Object invoke(InvocationRequest invocation) throws Throwable
   {
      log.debug(this + " received " + invocation);

      final Object parameter = invocation.getParameter();

      if ("ignore".equals(parameter))
      {
         // used in stress tests, do not accumulate record the invocation in history, since the
         // client is goint to send a lot of them ....
         log.debug(this + " ignoring invocation");
         return null;
      }

      if (parameter instanceof SocketTransportCausalityTest.SimpleInvocation)
      {
         SocketTransportCausalityTest.SimpleInvocation inv = (SocketTransportCausalityTest.SimpleInvocation)parameter;

         synchronized (this)
         {
            int clientNum = inv.clientNumber;

            int lastCount = this.counters[clientNum];

            log.trace("Received client " + clientNum + " num " + inv.num);

            if (inv.num != lastCount + 1)
            {
               //Failed - out of sequence
               failed = true;

               log.trace("Failed!!!! out of sequence");
            }

            counters[clientNum] = inv.num;

            return null;
         }

      }

      invocationHistory.put(dirtyCopy(invocation));

      if (parameter instanceof OnewayCallbackTrigger)
      {
         // send all oneway invocations from a different thread to avoid blocking the worker thread
         // that has to return and write a response on the wire

         new Thread(new Runnable()
         {
            public void run()
            {
               OnewayCallbackTrigger t = (OnewayCallbackTrigger)parameter;
               String payload = t.getPayload();
               long[] triggerTimes = t.getTriggerTimes();

               for(int i = 0; i < triggerTimes.length; i++)
               {
                  Callback callback = new Callback(payload + (i != 0 ? Integer.toString(i) : ""));

                  try
                  {
                     Thread.sleep(triggerTimes[i]);
                  }
                  catch(InterruptedException e)
                  {
                     log.error("interrupted", e);
                     return;
                  }

                  // seding a callback asynchronously
                  pushToClient(callback, false);
               }
            }
         }, "Oneway Invoker Thread").start();

         log.debug(this + " started a new oneway invoker thread");

      }

      return null;
   }

   public void addListener(InvokerCallbackHandler callbackHandler)
   {
      synchronized(callbackListeners)
      {
         callbackListeners.add(callbackHandler);
      }
   }

   public void removeListener(InvokerCallbackHandler callbackHandler)
   {
      synchronized(callbackListeners)
      {
         callbackListeners.remove(callbackHandler);
      }
   }

   // TestableSubsystem implementation ----------------------------------------------------------

   public InvocationRequest getNextInvocation(long timeout) throws InterruptedException
   {
      return (InvocationRequest)invocationHistory.poll(timeout);
   }

   public boolean isFailed()
   {
      synchronized (this)
      {
         return failed;
      }
   }

   // Public ---------------------------------------------------------------------------------------

   public String toString()
   {
      return "RemotingTestSubsystem[" + Integer.toHexString(hashCode()) + "]";
   }

   // Package protected ----------------------------------------------------------------------------

   // Protected ------------------------------------------------------------------------------------

   // Private --------------------------------------------------------------------------------------

   private synchronized void pushToClient(Callback callback, boolean sendSynchronously)
   {
      // make a copy to avoid ConcurrentModificationException
      List callbackListenersCopy;
      synchronized(callbackListeners)
      {
         callbackListenersCopy = new ArrayList(callbackListeners);
      }

      for(Iterator i = callbackListenersCopy.iterator(); i.hasNext(); )
      {
         ServerInvokerCallbackHandler h = (ServerInvokerCallbackHandler)i.next();
         try
         {
            if (sendSynchronously)
            {
               log.debug("pushing synchronous callback " + callback + " to " + h);
               h.handleCallback(callback);
            }
            else
            {
               log.debug("pushing asynchronous callback " + callback + " to " + h);
               h.handleCallbackOneway(callback);
            }
         }
         catch(Exception e)
         {
            log.error("Sending callback failed", e);
         }
      }
   }

   // Inner classes --------------------------------------------------------------------------------
}
TOP

Related Classes of org.jboss.test.thirdparty.remoting.util.RemotingTestSubsystem

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.