Package org.xmlBlaster.test

Source Code of org.xmlBlaster.test.MsgInterceptor

/*------------------------------------------------------------------------------
Name:      MsgInterceptor.java
Project:   org.xmlBlasterProject:   xmlBlaster.org
Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
------------------------------------------------------------------------------*/
package org.xmlBlaster.test;

import java.util.logging.Logger;
import org.xmlBlaster.client.I_Callback;
import org.xmlBlaster.client.I_StreamingCallback;
import org.xmlBlaster.client.qos.UpdateQos;
import org.xmlBlaster.client.qos.UpdateReturnQos;
import org.xmlBlaster.client.qos.PublishReturnQos;
import org.xmlBlaster.client.key.UpdateKey;
import org.xmlBlaster.contrib.I_Update;
import org.xmlBlaster.util.Global;
import org.xmlBlaster.util.XmlBlasterException;
import org.xmlBlaster.util.MsgUnit;
import org.xmlBlaster.util.def.ErrorCode;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.InterruptedException;
import java.util.Map;
import java.util.Vector;

import junit.framework.Assert;
import java.lang.ref.WeakReference;

/**
* Intercepts incoming message in update() and collects them in a Vector for nice handling.
*/
public class MsgInterceptor extends Assert implements I_Callback, I_StreamingCallback, I_Update
{
   private final WeakReference weakglob;
   private final WeakReference weaklog;
   private I_Callback testsuite;
   //private Msgs msgs = null;
   private int verbosity = 2;
   private boolean countErased;
   private I_StreamingCallback streamTestsuite;
   private I_Update contribTestsuite;
   private byte[] msgContent;
  
   /**
    * @param testsuite If != null your update() variant will be called as well
    */
   public MsgInterceptor(Global glob, Logger log, I_Callback testsuite, I_StreamingCallback streamTestsuite) {
      this(glob, log, testsuite);
      this.streamTestsuite = streamTestsuite;
   }

   /**
    * @param testsuite If != null your update() variant will be called as well
    */
   public MsgInterceptor(Global glob, Logger log, I_Callback testsuite, I_Update contribTestsuite) {
      this(glob, log, testsuite);
      this.contribTestsuite = contribTestsuite;
   }

   /**
    * @param testsuite If != null your update() variant will be called as well
    */
   public MsgInterceptor(Global glob, Logger log, I_Callback testsuite) {
      this.weakglob = new WeakReference(glob);
      this.weaklog = new WeakReference(log);
      this.testsuite = testsuite;
      //this.msgs = new Msgs();
   }

   public final Global getGlobal() {
      return (Global)this.weakglob.get();
   }

   public final Logger getLog() {
      return (Logger)this.weaklog.get();
   }

   public void setLogPrefix(String prefix) {
   }

   /**
    * 0: no logging
    * 1: simple logging
    * 2: dump messages on arrival
    */
   public void setVerbosity(int val) {
      this.verbosity = val;
   }

   /*
    * Contains all update() messages in a Vector, but not erase events.
   public Msgs getMsgs() {
      return this.msgs;
   }
    */

   /**
    * @param countErased Set to true to count the erased notifications as well
    */
   public void countErased(boolean countErased) {
      this.countErased = countErased;
   }

   /**
    * This is the callback method (I_Callback) invoked from xmlBlaster
    * It directly calls the update method from the testsuite (delegation)
    */
   public String update(String cbSessionId, UpdateKey updateKey, byte[] content, UpdateQos updateQos) throws XmlBlasterException {
      String contentStr = new String(content);
     
      if (this.verbosity == 1) {
         String cont = (contentStr.length() > 10) ? (contentStr.substring(0,10)+"...") : contentStr;
         getLog().info("Receiving update of a message oid=" + updateKey.getOid() +
                   " priority=" + updateQos.getPriority() +
                   " state=" + updateQos.getState() +
                   " content=" + cont);
      }
      else if (this.verbosity == 2) {
         getLog().info("Receiving update #" + (count()+1) + " of a message cbSessionId=" + cbSessionId +
                      updateKey.toXml() + "\n" + new String(content) + updateQos.toXml());
      }

      if (this.countErased || !updateQos.isErased()) {
         add(new Msg(cbSessionId, updateKey, content, updateQos));
      }
      if (testsuite != null)
         return testsuite.update(cbSessionId, updateKey, content, updateQos);
      else {
         UpdateReturnQos qos = new UpdateReturnQos(getGlobal());
         return qos.toXml();
      }
   }
  
   /**
    * This is the callback method (I_StreamingCallback) invoked from xmlBlaster
    * It directly calls the update method from the testsuite (delegation)
    */
   public String update(String cbSessionId, UpdateKey updateKey, InputStream is, UpdateQos updateQos) throws XmlBlasterException {
     
      String ret = null;
      if (this.streamTestsuite != null) {
         try {
            ret = this.streamTestsuite.update(cbSessionId, updateKey, is, updateQos);
         }
         catch (IOException ex) {
            throw new XmlBlasterException(Global.instance(), ErrorCode.INTERNAL_ILLEGALARGUMENT, "update", "update", ex);
         }
      }
      else {
         fail("The testsuite instance has not been defined");
      }
      if (this.countErased || !updateQos.isErased()) {
         add(new Msg(cbSessionId, updateKey, msgContent, updateQos));
      }
      return ret;
   }


   /**
    * This is the callback method (I_StreamingCallback) invoked from xmlBlaster
    * It directly calls the update method from the testsuite (delegation)
    */
   public void update(String topic, InputStream is, Map attrMap) throws Exception {
      if (this.contribTestsuite != null) {
         try {
            this.contribTestsuite.update(topic, is, attrMap);
         }
         catch (IOException ex) {
            throw new XmlBlasterException(Global.instance(), ErrorCode.INTERNAL_ILLEGALARGUMENT, "update", "update", ex);
         }
      }
      if (verbosity > 0 && is != null) {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         int val = 0;
         byte[] buf = new byte[1000];
         while ( (val = is.read(buf)) > -1)
            baos.write(buf, 0, val);
         System.out.println(new String(baos.toByteArray()));
      }
      add(new Msg(null, null, new byte[0], null));
   }

   /**
    * @see #waitOnUpdate(long, String, String, int)
    */
   public int waitOnUpdate(final long timeout, int countExpected) {
      return waitOnUpdate(timeout, null, null, countExpected);
   }

   /**
    * Waits until the given number of messages arrived,
    * the messages must match the given oid and state.
    * It is not checked if more messages would arrive as we return after
    * countExpected are here.
    * <p>
    * ERASE notifies are not returned
    * </p>
    * <p>
    * This method does not assert() it return the number of messages arrived
    * which you can use to assert yourself.
    * </p>
    * @param timeout in milliseconds
    * @param oid The expected message oid, if null the oid is not checked (all oids are OK)
    * @param state The expected state, if null the state is not checked (all states are OK)
    *
    * @return Number of messages arrived
    */
   public int waitOnUpdate(final long timeout, String oid, String state, int countExpected) {
      long pollingInterval = 50L// check every 0.05 seconds
      if (timeout < 50pollingInterval = timeout / 10L;
      long sum = 0L;
      int countArrived = 0;
      while (true) {
         countArrived = getMsgs(oid, state).length;
         if (countArrived >= countExpected)
            return countArrived; // OK, no timeout
         try {
            Thread.sleep(pollingInterval);
         }
         catch( InterruptedException i)
         {}

         sum += pollingInterval;
         if (sum > timeout) {
            getLog().severe("timeout=" + timeout + " occurred for " + oid + " state=" + state + " countExpected=" + countExpected + " countArrived=" + countArrived);
            return countArrived; // Timeout occurred
         }
      }
   }

   /**
    * Sleeps until timeout and returns the arrived messages.
    * <p>
    * ERASE notifies are not returned
    * </p>
    * @see #waitOnUpdate(long, String, String)
    */
   public int waitOnUpdate(final long timeout) {
      return waitOnUpdate(timeout, null, null);
   }

   /**
    * Sleeps until timeout and returns the number of arrived messages filtered by oid and state.
    * <p>
    * ERASE notifies are not returned
    * </p>
    * @param timeout in milliseconds
    * @param oid The expected message oid, if null the oid is not checked (all oids are OK)
    * @param state The expected state, if null the state is not checked (all states are OK)
    *
    * @return Number of messages arrived
    */
   public int waitOnUpdate(final long timeout, String oid, String state) {
      try {
         Thread.sleep(timeout);
      }
      catch( InterruptedException i)
      {}
      return getMsgs(oid, state).length;
   }


   // Holding all messages
   private Vector updateVec = new Vector();
  
   public void add(Msg msg) {
      this.updateVec.addElement(msg);
  }
  
   public void remove(Msg msg) {
      this.updateVec.removeElement(msg);
   }
  
   /**
    * Clears all arrived messages AND the countErased flag to false
    */
   public void clear() {
      this.updateVec.clear();
      this.countErased = false;
   }

   /**
    * Access the updated message filtered by the given oid and state.
    * @param oid if null the oid is not checked
    * @param state if null the state is not checked
    */
   public Msg[] getMsgs(String oid, String state) {
      Vector ret = new Vector();
      for (int i=0; i<this.updateVec.size(); i++) {
         Msg msg = (Msg)this.updateVec.elementAt(i);
         //System.out.println("MsgInterceptor: Checking msg oid='" + msg.getOid() + "' with state='" + msg.getState() + "' against '" + oid + "' '" + state + "'");
         if (
             (oid == null || oid.equals(msg.getOid())) &&
             (state == null || state.equals(msg.getState()))
            ) {
            ret.addElement(msg);
            //System.out.println("MsgInterceptor: FOUND: Checking msg oid='" + msg.getOid() + "' with state='" + msg.getState() + "' against '" + oid + "' '" + state + "'");
         }
      }
      return  (Msg[])ret.toArray(new Msg[ret.size()]);
   }

   public Msg[] getMsgs() {
      return getMsgs(null, null);
   }

   /**
    * Access the updated message filtered by the given oid and state.
    * @return null or the message
    * @exception If more than one message is available
    */
   public Msg getMsg(String oid, String state) throws XmlBlasterException {
      Msg[] msgs = getMsgs(oid, state);
      //System.out.println("MsgInterceptor: FOUND " + msgs.length + " entries for msg oid='" + oid + "' with state='" + state);
      if (msgs.length > 1)
         throw new XmlBlasterException("Msgs", "update(oid=" + oid + ", state=" + state + ") " + msgs.length + " arrived instead of zero or one");
      if (msgs.length == 0)
         return null;
      return msgs[0];
   }

   public int count() {
      return this.updateVec.size();
   }

   /**
    * Compares all messages given by parameter 'expectedArr' and compare
    * them with the received ones. On failure a junit - assert() is thrown.
    * <p>
    * The correct sequence and the message data is checked.
    * </p>
    * @param expectedArr The published messages which we expect here as updates
    * @param secretCbSessionId If not null it is checked as well
    */
   public void compareToReceived(MsgUnit[] expectedArr, String secretCbSessionId) {
      assertEquals("We have received " + count() + " messages only", expectedArr.length, count());
     
      for(int i=0; i<expectedArr.length; i++) {
         MsgUnit expected = expectedArr[i];
         Msg msg = (Msg)this.updateVec.elementAt(i);
         if (secretCbSessionId != null) {
            assertEquals("The secretCbSessionId is wrong", secretCbSessionId, msg.getCbSessionId());
         }
         msg.compareMsg(expected);
      }
   }

   /**
    * Compares all messages given by parameter 'expectedArr' and compare
    * them with the received ones. On failure a junit - assert() is thrown.
    * <p>
    * Especially the sequence and the rcvTimestamp is checked.
    * </p>
    * @param expectedArr The published messages which we expect here as updates
    */
   public void compareToReceived(PublishReturnQos[] expectedArr) {
      assertEquals("We have received " + count() + " messages only", expectedArr.length, count());

      for(int i=0; i<expectedArr.length; i++) {
         Msg msg = (Msg)this.updateVec.elementAt(i);
         msg.compareMsg(expectedArr[i]);
      }
   }
  
   public void setMsgContent(byte[] msgContent) {
      this.msgContent = msgContent;
   }
  
} // MsgInterceptor
TOP

Related Classes of org.xmlBlaster.test.MsgInterceptor

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.