Package org.xmlBlaster.test.contrib.filewatcher

Source Code of org.xmlBlaster.test.contrib.filewatcher.TestFileWatcherPlugin

/*------------------------------------------------------------------------------
Name:      TestPollerPlugin.java
Project:   xmlBlaster.org
Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
------------------------------------------------------------------------------*/
package org.xmlBlaster.test.contrib.filewatcher;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

import java.util.logging.Logger;
import org.xmlBlaster.client.I_Callback;
import org.xmlBlaster.client.key.SubscribeKey;
import org.xmlBlaster.client.key.UnSubscribeKey;
import org.xmlBlaster.client.key.UpdateKey;
import org.xmlBlaster.client.qos.ConnectQos;
import org.xmlBlaster.client.qos.DisconnectQos;
import org.xmlBlaster.client.qos.SubscribeQos;
import org.xmlBlaster.client.qos.UnSubscribeQos;
import org.xmlBlaster.client.qos.UpdateQos;
import org.xmlBlaster.contrib.I_Info;
import org.xmlBlaster.contrib.PropertiesInfo;
import org.xmlBlaster.contrib.filewatcher.Publisher;
import org.xmlBlaster.test.MsgInterceptor;
import org.xmlBlaster.util.Global;
import org.xmlBlaster.util.XmlBlasterException;
import org.xmlBlaster.util.qos.address.Address;

import junit.framework.TestCase;


/**
* <p>
* This is an interesting example, since it creates a XmlBlaster server instance
* in the same JVM , but in a separate thread, talking over CORBA with it.
* <p>
* Invoke examples:<br />
* <pre>
*   java junit.textui.TestRunner -noloading org.xmlBlaster.test.client.TestFilePollerPlugin
*   java junit.swingui.TestRunner -noloading org.xmlBlaster.test.client.TestFilePollerPlugin
* </pre>
* @see org.xmlBlaster.client.I_XmlBlasterAccess
*/
public class TestFileWatcherPlugin extends TestCase implements I_Callback {
   private static String ME = "TestFilePollerPlugin";
   private Global global;
   private static Logger log = Logger.getLogger(TestFileWatcherPlugin.class.getName());
   private Global connGlobal;
   private String oid = "filepollerTest";
   private String dirName;
   private String dirNameSent;
   private String dirNameDiscarded;
   private MsgInterceptor updateInterceptor;

   public TestFileWatcherPlugin() {
      this(null);
   }

   private void getBaseDir() {
      try {
         File dummy = File.createTempFile("dummy", null);
         String path = dummy.getCanonicalPath();
         dummy.delete();
         int pos = path.lastIndexOf(File.separator);
         if (pos < 0)
            fail("the temporary path is not absolute '" + path + "'");
         this.dirName = path.substring(0, pos) + "/testsuitePoller";
         log.info("WILL USE THE DIRECTORY '" + this.dirName + "' AS THE BASE DIRECTORY");
         this.dirNameSent = this.dirName + "/Sent";
         this.dirNameDiscarded = this.dirName + "/Discarded";
      }
      catch(Exception ex) {
         ex.printStackTrace();
         fail("exception occured when trying to find out temporary path");
      }
   }
  
  
   public TestFileWatcherPlugin(Global global) {
      super("TestFilePollerPlugin");
      this.global = global;
      if (this.global == null) {
         this.global = new Global();
         this.global.init((String[])null);
      }

      getBaseDir();
   }

   /**
    * Sets up the fixture.
    * <p />
    * Connect to xmlBlaster and login
    */
   protected void setUp() {
      /*
      File file = new File(this.dirName);
      if (file.exists())
         FileLocator.deleteDir(file);
      */
      try {
         this.connGlobal = this.global.getClone(null);
         this.updateInterceptor = new MsgInterceptor(this.connGlobal, log, null);
         this.connGlobal.getXmlBlasterAccess().connect(new ConnectQos(this.connGlobal), this.updateInterceptor);
         SubscribeQos subQos = new SubscribeQos(this.connGlobal);
         subQos.setWantInitialUpdate(false);
         this.connGlobal.getXmlBlasterAccess().subscribe(new SubscribeKey(this.connGlobal, this.oid), subQos);
      }
      catch (XmlBlasterException ex) {
         ex.printStackTrace();
         fail("aborting since exception ex: " + ex.getMessage());
      }
   }
  
  
   /**
    * Tears down the fixture.
    * <p />
    * cleaning up .... erase() the previous message OID and logout
    */
   protected void tearDown() {
      log.info("Entering tearDown(), test is finished");
      cleanUpDirs();
      try {
         this.connGlobal.getXmlBlasterAccess().unSubscribe(new UnSubscribeKey(this.connGlobal, this.oid), new UnSubscribeQos(this.connGlobal));
         this.connGlobal.getXmlBlasterAccess().disconnect(new DisconnectQos(this.connGlobal));
         this.connGlobal.shutdown();
         this.connGlobal = null;
      }
      catch (XmlBlasterException ex) {
         ex.printStackTrace();
         fail("aborting since exception ex: " + ex.getMessage());
      }
   }

   public String update(String cbSessionId, UpdateKey updateKey, byte[] content, UpdateQos updateQos) throws XmlBlasterException {
      String contentStr = new String(content);
      String cont = (contentStr.length() > 10) ? (contentStr.substring(0,10)+"...") : contentStr;
      log.info("Receiving update of a message oid=" + updateKey.getOid() +
                        " priority=" + updateQos.getPriority() +
                        " state=" + updateQos.getState() +
                        " content=" + cont);
      log.info("further log for receiving update of a message cbSessionId=" + cbSessionId +
                     updateKey.toXml() + "\n" + new String(content) + updateQos.toXml());
      log.severe("update: should never be invoked (msgInterceptors take care of it since they are passed on subscriptions)");

      return "OK";
   }

   /**
    * Tests the creation of the necessary directories
    *
    */
   public void testDirectories() {
      // absolute path
      I_Info prop = new PropertiesInfo(new Properties());
      prop.put("mom.topicName", "dummy");
      prop.put("filewatcher.directoryName", this.dirName);
      prop.put("filewatcher.sent", this.dirNameSent);
      prop.put("filewatcher.discarded", this.dirNameDiscarded);
      try {
         new Publisher(this.global, "test", prop);
      }
      catch (XmlBlasterException ex) {
         ex.printStackTrace();
         assertTrue("An exception should not occur here " + ex.getMessage(), false);
      }
      checkDirs();

      // repeat that with already existing directories
      prop = new PropertiesInfo(new Properties());
      prop.put("mom.topicName", "dummy");
      prop.put("filewatcher.directoryName", this.dirName);
      prop.put("filewatcher.sent", this.dirNameSent);
      prop.put("filewatcher.discarded", this.dirNameDiscarded);
      try {
         new Publisher(this.global, "test", prop);
      }
      catch (XmlBlasterException ex) {
         ex.printStackTrace();
         assertTrue("An exception should not occur here " + ex.getMessage(), false);
      }
      checkDirs();
      cleanUpDirs();

      // relative path are added to the 'directoryName'
      prop = new PropertiesInfo(new Properties());
      prop.put("mom.topicName", "dummy");
      prop.put("filewatcher.directoryName", this.dirName);
      prop.put("filewatcher.sent", "Sent");
      prop.put("filewatcher.discarded", "Discarded");
      try {
         new Publisher(this.global, "test", prop);
      }
      catch (XmlBlasterException ex) {
         ex.printStackTrace();
         assertTrue("An exception should not occur here " + ex.getMessage(), false);
      }
      checkDirs();
      // relative path are added to the 'directoryName' repeat with existing directories
      prop = new PropertiesInfo(new Properties());
      prop.put("mom.topicName", "dummy");
      prop.put("filewatcher.directoryName", this.dirName);
      prop.put("filewatcher.sent", "Sent");
      prop.put("filewatcher.discarded", "Discarded");
      try {
         new Publisher(this.global, "test", prop);
      }
      catch (XmlBlasterException ex) {
         ex.printStackTrace();
         assertTrue("An exception should not occur here " + ex.getMessage(), false);
      }
      checkDirs();
     
      cleanUpDirs();
     
      // now some which should fail:
      // existing file but not a directory
      File file = new File(this.dirName);
      try {
         file.createNewFile();
      }
      catch (IOException ex) {
         assertTrue("could not create the file '" + this.dirName + "'", false);
      }
     
      prop = new PropertiesInfo(new Properties());
      prop.put("mom.topicName", "dummy");
      prop.put("filewatcher.directoryName", this.dirName);
      prop.put("filewatcher.sent", "Sent");
      prop.put("filewatcher.discarded", "Discarded");
      try {
         new Publisher(this.global, "test", prop);
         assertTrue("an exception should occur since '" + this.dirName + "' is a file and should be a directory", false);
      }
      catch (XmlBlasterException ex) {
         log.info("Exception is OK here");
      }
      cleanUpDirs();
     
      try {
         file = new File(this.dirName);
         boolean ret = file.mkdir();
         assertTrue("could not create directory '" + this.dirName + "'", ret);
         file = new File(this.dirNameSent);
         file.createNewFile();
      }
      catch (IOException ex) {
         assertTrue("could not create the file '" + this.dirNameSent + "'", false);
      }
     
      prop = new PropertiesInfo(new Properties());
      prop.put("mom.topicName", "dummy");
      prop.put("filewatcher.directoryName", this.dirName);
      prop.put("filewatcher.sent", "Sent");
      prop.put("filewatcher.discarded", "Discarded");
      try {
         new Publisher(this.global, "test", prop);
         assertTrue("an exception should occur since '" + this.dirName + "' is a file and should be a directory", false);
      }
      catch (XmlBlasterException ex) {
         log.info("Exception is OK here");
      }
      cleanUpDirs();
   }

   private void singleDump(String filename, int filesize, String lockExt, long delay, boolean deliver, boolean absSubPath, String movedDir) {
      String okFile = this.dirName + File.separator + filename;
      byte[] okBuf = writeFile(okFile, filesize, lockExt, delay);
      int ret = this.updateInterceptor.waitOnUpdate(delay);
      boolean exist = false;
      int sent = 1;
      String txt = "";
      if (!deliver) {
         exist = true;
         sent = 0;
         txt = "not ";
      }
      assertEquals("expected '" + sent + "' update", sent, ret);
      File tmp = new File(okFile);
      assertEquals("the file '" + okFile + "' should " + txt + "have been removed", exist, tmp.exists());
      if (deliver) {
         checkMoved(filename, absSubPath, movedDir);
         boolean sameContent = compareContent(okBuf, this.updateInterceptor.getMsgs()[0].getContent());
         assertTrue("the content of the file is not the same as the arrived content of the update method", sameContent);
         String fileName = this.updateInterceptor.getMsgs()[0].getUpdateQos().getClientProperty("_filename", (String)null);
         assertNotNull("The fileName is null", fileName);
         assertEquals("", filename, fileName);
      }
      this.updateInterceptor.clear();
   }
  
   private void checkMoved(String name, boolean absSubPath, String subDirName) {
      if (subDirName == null)
         return;
      File discDir = null;
      if (absSubPath) {
         discDir = new File(subDirName);
      }
      else {
         discDir = new File(new File(this.dirName), subDirName);
      }
      File tmp = new File(discDir, name);
      assertTrue("The directory '" + subDirName + "' must exist", discDir.exists());
      assertTrue("The file '" + name + "' must exist in '" + subDirName + "' directory", tmp.exists());
   }
  
  
   private void doPublish(I_Info prop, boolean deliverFirst, boolean deliverSecond, boolean absSubPath) {
      String lockExt = prop.get("filewatcher.lockExtention", null);
     
      prop.put("mom.topicName", this.oid);
      prop.put("filewatcher.directoryName", this.dirName);

      int maximumSize = 10000;
      long delaySinceLastChange = 1000L;
      long pollInterval = 600L;
      prop.put("filewatcher.maximumFileSize", "" + maximumSize);
      prop.put("filewatcher.delaySinceLastFileChange", "" + delaySinceLastChange);
      prop.put("filewatcher.pollInterval", "" + pollInterval);
      prop.put("filewatcher.warnOnEmptyFileDelay", "1000");
     
      String sent = prop.get("filewatcher.sent", null);
      String discarded = prop.get("filewatcher.discarded", null);
     
      org.xmlBlaster.engine.ServerScope engineGlobal = new org.xmlBlaster.engine.ServerScope();
      prop.put("mom.connectQos", this.getConnectQos(engineGlobal));
     
      Publisher publisher = null;
      try {
         publisher = new Publisher(engineGlobal, "test", prop);
         publisher.init();

         this.updateInterceptor.clear();
         // too big
         String tooBig = this.dirName + File.separator + "tooBig.dat";
         writeFile(tooBig, maximumSize+1, lockExt, delaySinceLastChange* 2);
         int ret = this.updateInterceptor.waitOnUpdate(delaySinceLastChange* 2);
         assertEquals("expected no updates", 0, ret);

         File tmp = new File(tooBig);
         if (deliverFirst) {
            assertFalse("the file '" + tooBig + "' should have been removed", tmp.exists());
            checkMoved("tooBig.dat", absSubPath, discarded);
         }
         else {
            assertTrue("the file '" + tooBig + "' should still be here", tmp.exists());
         }

         this.updateInterceptor.clear();

         singleDump("ok.dat", maximumSize-1, lockExt, delaySinceLastChange* 2, deliverFirst, absSubPath, sent);
         singleDump("ok.gif", maximumSize-1, lockExt, delaySinceLastChange* 2, deliverSecond, absSubPath, sent);
      }
      catch (XmlBlasterException ex) {
         ex.printStackTrace();
         assertTrue("An exception should not occur here " + ex.getMessage(), false);
      }
      finally {
         if (publisher != null) {
            try {
               publisher.shutdown();
            }
            catch (Throwable ex) {
               ex.printStackTrace();
               fail("exception when shutting down the poller " + ex.getMessage());
            }
         }
      }
   }
  
   public void testSimplePublish() {
      boolean deliverDat = true;
      boolean deliverGif = true;
      boolean absSubPath = true;
      I_Info prop = new PropertiesInfo(new Properties());
      doPublish(prop, deliverDat, deliverGif, absSubPath);
   }

   public void testSimplePublishWithFilter() {
      boolean deliverDat = false;
      boolean deliverGif = true;
      boolean absSubPath = true;
      I_Info prop = new PropertiesInfo(new Properties());
      prop.put("filewatcher.fileFilter", "*.gif");
      doPublish(prop, deliverDat, deliverGif, absSubPath);
   }
  
   public void testSimplePublishWithFilterRegex() {
      boolean deliverDat = true;
      boolean deliverGif = true;
      boolean absSubPath = true;
      I_Info prop = new PropertiesInfo(new Properties());
      prop.put("filewatcher.filterType", "regex");
      // note that the double backslash would be simple if read from the configuration file
      prop.put("filewatcher.fileFilter", "(.*\\.dat)|(.*\\.gif)");
      doPublish(prop, deliverDat, deliverGif, absSubPath);
   }
  
   public void testPublishWithMoveAbsolute() {
      boolean deliverDat = true;
      boolean deliverGif = true;
      boolean absSubPath = true;
      I_Info prop = new PropertiesInfo(new Properties());
      prop.put("filewatcher.sent", this.dirName + File.separator + "Sent");
      prop.put("filewatcher.discarded", this.dirName + File.separator + "Discarded");
      doPublish(prop, deliverDat, deliverGif, absSubPath);
   }

   public void testPublishWithMoveRelative() {
      boolean deliverDat = true;
      boolean deliverGif = true;
      boolean absSubPath = false;
      I_Info prop = new PropertiesInfo(new Properties());
      prop.put("filewatcher.sent", "Sent");
      prop.put("filewatcher.discarded", "Discarded");
      doPublish(prop, deliverDat, deliverGif, absSubPath);
   }

   public void testPublishWithMoveRelativeLockMode() {
      boolean deliverDat = true;
      boolean deliverGif = true;
      boolean absSubPath = false;
      I_Info prop = new PropertiesInfo(new Properties());
      prop.put("filewatcher.sent", "Sent");
      prop.put("filewatcher.discarded", "Discarded");
      prop.put("filewatcher.lockExtention", "*.lck");
      doPublish(prop, deliverDat, deliverGif, absSubPath);
   }

   public void testSimplePublishWithFilterLockMode() {
      boolean deliverDat = false;
      boolean deliverGif = true;
      boolean absSubPath = true;
      I_Info prop = new PropertiesInfo(new Properties());
      prop.put("filewatcher.fileFilter", "*.gif");
      prop.put("filewatcher.lockExtention", "*.lck");
      doPublish(prop, deliverDat, deliverGif, absSubPath);
   }
  
   /*
      prop.put("sent", "Sent");
      prop.put("discarded", "Discarded");
      prop.put("publishKey", "");
      prop.put("publishQos", "");
      prop.put("connectQos", "");
      prop.put("loginName", "");
      prop.put("password", "");
      prop.put("fileFilter", "");
      prop.put("lockExtention", "*.lck");
*/

   private boolean compareContent(byte[] buf1, byte[] buf2) {
      if (buf1 == null && buf2 == null)
         return true;

      if (buf1 == null || buf2 == null)
         return false;
     
      if (buf1.length != buf2.length)
         return false;
      for (int i=0; i < buf1.length; i++) {
         if (buf1[i] != buf2[i])
            return false;
      }
      return true;
   }
  
   private byte[] writeFile(String filename, int size, String lockExt, long timeToWait) {
      try {
         File lock = null;
         if (lockExt != null) {
            String tmp = filename + lockExt.substring(1);
            lock = new File(tmp);
            boolean ret = lock.createNewFile();
            assertTrue("could not create lock file '" + tmp + "'", ret);
            int upd = this.updateInterceptor.waitOnUpdate(timeToWait);
            assertEquals("when writing lock file should not update", 0, upd);
         }
         else
            this.updateInterceptor.waitOnUpdate(timeToWait);

         byte[] buf = new byte[size];
         for (int i=0; i < size; i++) {
            buf[i] = (byte)i;
         }
         FileOutputStream fos = new FileOutputStream(filename);
         fos.write(buf);
         fos.close();
        
         if (lockExt != null) {
            int upd = this.updateInterceptor.waitOnUpdate(timeToWait);
            assertEquals("when still locked by lockfile should not update", 0, upd);
            File tmp = new File(filename);
            assertTrue("file '" + filename + "' should still exist since lock file exists", tmp.exists());
         }
         else
            this.updateInterceptor.waitOnUpdate(timeToWait);
         if (lock != null) {
            boolean ret = lock.delete();
            assertTrue("could not remove lock file '" + filename + lockExt.substring(1) + "'", ret);
         }
         return buf;
      }
      catch (IOException ex) {
         ex.printStackTrace();
         fail("could not write to file '" + filename + "'");
         return null; // fake return to make compiler happy
      }
   }
  
  
   private void checkDirs() {
      File file = new File(this.dirName);
      assertTrue("file '" + this.dirName + "' does not exist", file.exists());
      file = new File(this.dirNameSent);
      assertTrue("file '" + this.dirNameSent + "' does not exist", file.exists());
      file = new File(this.dirNameDiscarded);
      assertTrue("file '" + this.dirNameDiscarded + "' does not exist", file.exists());
   }
  
   private String getConnectQos(Global glob) {
      try {
         ConnectQos connQos = new ConnectQos(glob, "filePollerTestUser", "secret");
         connQos.setMaxSessions(100);
         Address address = connQos.getAddress();
         address.setPingInterval(0L);
         address.setCollectTime(0L);
         connQos.getClientQueueProperty().setType("RAM");
         connQos.getClientQueueProperty().setVersion("1.0");
         return connQos.toXml();
      }
      catch (XmlBlasterException ex) {
         fail("an exception when building the connect qos: " + ex.getMessage());
         return null;
      }
   }

   private void delete(String filename) {
      try {
         (new File(filename)).delete();
      }
      catch (Throwable ex) {
      }
   }
  
   private void cleanUpDirs() {
      delete(this.dirNameSent + File.separator + "ok.dat");
      delete(this.dirNameSent + File.separator + "ok.gif");
      delete(this.dirNameSent);
      delete(this.dirNameDiscarded + File.separator + "tooBig.dat");
      delete(this.dirNameDiscarded);
      delete(this.dirName + File.separator + "ok.dat");
      delete(this.dirName + File.separator + "ok.dat.lck");
      delete(this.dirName + File.separator + "ok.gif");
      delete(this.dirName + File.separator + "ok.gif.lck");
      delete(this.dirName + File.separator + "tooBig.dat");
      delete(this.dirName + File.separator + "tooBig.dat.lck");
     
      delete(this.dirName);
   }
  
  
   /**
    * Invoke: java org.xmlBlaster.test.client.TestFilePollerPlugin
    * <p />
    * @deprecated Use the TestRunner from the testsuite to run it:<p />
    * <pre>   java -Djava.compiler= junit.textui.TestRunner org.xmlBlaster.test.client.TestFilePollerPlugin</pre>
    */
   public static void main(String args[]) {
      Global global = new Global();
      if (global.init(args) != 0) {
         System.out.println(ME + ": Init failed");
         System.exit(1);
      }

      TestFileWatcherPlugin test = new TestFileWatcherPlugin(global);

      test.setUp();
      test.testSimplePublish();
      test.tearDown();

      test.setUp();
      test.testDirectories();
      test.tearDown();

      test.setUp();
      test.testSimplePublishWithFilter();
      test.tearDown();

      test.setUp();
      test.testSimplePublishWithFilterRegex();
      test.tearDown();

      test.setUp();
      test.testPublishWithMoveAbsolute();
      test.tearDown();

      test.setUp();
      test.testPublishWithMoveRelative();
      test.tearDown();

      test.setUp();
      test.testPublishWithMoveRelativeLockMode();
      test.tearDown();

      test.setUp();
      test.testSimplePublishWithFilterLockMode();
      test.tearDown();
   }
}
TOP

Related Classes of org.xmlBlaster.test.contrib.filewatcher.TestFileWatcherPlugin

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.