[jboss-cvs] JBossAS SVN: r74877 - in projects/vfs/trunk/src/test/java/org/jboss/test/virtual: support/ps and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Jun 20 10:04:12 EDT 2008


Author: scott.stark at jboss.org
Date: 2008-06-20 10:04:12 -0400 (Fri, 20 Jun 2008)
New Revision: 74877

Added:
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/DeploymentPhase.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/MockProfileServiceRepository.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/ModificationInfo.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/VFSDeployment.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/VFSDeploymentFactory.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/VFSDeploymentImpl.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/hotdeploy/
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/hotdeploy/HDScanner.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/HDScannerTestCase.java
Log:
Try to reproduce the profileservice locking issues

Added: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/DeploymentPhase.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/DeploymentPhase.java	                        (rev 0)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/DeploymentPhase.java	2008-06-20 14:04:12 UTC (rev 74877)
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.virtual.support.ps;
+
+/**
+ * @author Scott.Stark at jboss.org
+ * @version $Revision:$
+ */
+public enum DeploymentPhase
+{
+   BOOTSTRAP, DEPLOYER, APPLICATION, APPLICATION_TRANSIENT
+
+}

Added: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/MockProfileServiceRepository.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/MockProfileServiceRepository.java	                        (rev 0)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/MockProfileServiceRepository.java	2008-06-20 14:04:12 UTC (rev 74877)
@@ -0,0 +1,678 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.virtual.support.ps;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.SyncFailedException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.zip.ZipInputStream;
+
+import org.jboss.logging.Logger;
+import org.jboss.test.virtual.support.ps.DeploymentPhase;
+import org.jboss.test.virtual.support.ps.ModificationInfo;
+import org.jboss.test.virtual.support.ps.VFSDeployment;
+import org.jboss.test.virtual.support.ps.VFSDeploymentFactory;
+import org.jboss.test.virtual.support.ps.ModificationInfo.ModifyStatus;
+import org.jboss.util.file.Files;
+import org.jboss.virtual.VFS;
+import org.jboss.virtual.VirtualFile;
+
+/**
+ * An implementation of DeploymentRepository that relies on java
+ * @author Scott.Stark at jboss.org
+ * @version $Revision:$
+ */
+public class MockProfileServiceRepository
+{
+   private static final Logger log = Logger.getLogger(MockProfileServiceRepository.class);
+
+   /** The server root container the deployments */
+   private File root;
+   /** The application phase deployments dir */
+   private File[] applicationDirs;
+   private LinkedHashMap<String,VFSDeployment> applicationCtxs = new LinkedHashMap<String,VFSDeployment>();
+   private Set<String> lockedApps = Collections.synchronizedSet(new HashSet<String>());
+   /** The last time the profile was modified */
+   private long lastModified;
+   /** A lock for the hot deployment/{@link #getModifiedDeployments()} */
+   private ReentrantReadWriteLock contentLock = new ReentrantReadWriteLock(true);
+   /** Should an attempt to overwrite existing content fail in {@link #addDeploymentContent(String, ZipInputStream, DeploymentPhase)}*/
+   private boolean failIfAlreadyExists = false;
+
+   public MockProfileServiceRepository(File root, URI[] appURIs)
+   {
+      this.root = root;
+      this.setApplicationURIs(appURIs);
+   }
+
+   public URI[] getApplicationURIs()
+   {
+      URI[] appURIs = new URI[applicationDirs.length];
+      for (int n = 0; n < applicationDirs.length; n ++)
+      {
+         File applicationDir = applicationDirs[n];
+         appURIs[n] = applicationDir.toURI();
+      }
+      return appURIs;
+   }
+   public void setApplicationURIs(URI[] uris)
+   {
+      applicationDirs = new File[uris.length];
+      for (int n = 0; n < uris.length; n ++)
+      {
+         URI uri = uris[n];
+         applicationDirs[n] = new File(uri);
+      }
+   }
+
+   public boolean exists()
+   {
+      return root.exists();
+   }
+
+   public long getLastModified()
+   {
+      return this.lastModified;
+   }
+
+   public URI getDeploymentURI(DeploymentPhase phase)
+   {
+      URI uri = null;
+      switch( phase )
+      {
+         case BOOTSTRAP:
+            uri = this.getBootstrapURI();
+            break;
+         case DEPLOYER:
+            break;
+         case APPLICATION:
+            uri = this.getApplicationURI();
+            break;
+      }
+      return uri;
+   }
+   public void setDeploymentURI(URI uri, DeploymentPhase phase)
+   {
+      switch( phase )
+      {
+         case BOOTSTRAP:
+            this.setBootstrapURI(uri);
+            break;
+         case DEPLOYER:
+            this.setDeployersURI(uri);
+            break;
+         case APPLICATION:
+            this.setApplicationURIs(new URI[]{uri});
+            break;
+      }
+   }
+   public Set<String> getDeploymentNames()
+   {
+      HashSet<String> names = new HashSet<String>();
+      names.addAll(applicationCtxs.keySet());
+      return names;
+   }
+   public Set<String> getDeploymentNames(DeploymentPhase phase)
+   {
+      HashSet<String> names = new HashSet<String>();
+      switch( phase )
+      {
+         case BOOTSTRAP:
+            break;
+         case DEPLOYER:
+            break;
+         case APPLICATION:
+            names.addAll(this.applicationCtxs.keySet());
+            break;
+      }
+      return names;      
+   }
+
+   /**
+    * 
+    */
+   public void addDeploymentContent(String name, InputStream contentIS, DeploymentPhase phase)
+      throws IOException
+   {
+      boolean trace = log.isTraceEnabled();
+      // Suspend hot deployment checking
+      if( trace )
+         log.trace("Aquiring content read lock");
+      contentLock.writeLock().lock();
+      try
+      {
+         // Write the content out
+         File contentRoot = getPhaseDir(phase);
+         if(contentRoot == null)
+            throw new FileNotFoundException("Failed to obtain content dir for phase: "+phase);
+         File contentFile = new File(contentRoot, name);
+         if(failIfAlreadyExists && contentFile.exists())
+            throw new SyncFailedException("Deployment content already exists: "+contentFile.getAbsolutePath());
+         FileOutputStream fos = new FileOutputStream(contentFile);
+         try
+         {
+            byte[] tmp = new byte[4096];
+            int read;
+            while((read = contentIS.read(tmp)) > 0)
+            {
+               if (trace)
+                  log.trace("write, " + read);
+               fos.write(tmp, 0, read);
+            }
+            fos.flush();
+         }
+         finally
+         {
+            try
+            {
+               fos.close();
+            }
+            catch (IOException ignored)
+            {
+            }
+         }
+         //contentIS.close();
+
+         // Lock the content
+         lockDeploymentContent(name, phase);
+      }
+      finally
+      {
+         // Allow hot deployment checking
+         contentLock.writeLock().unlock();
+         if(trace)
+            log.trace("Released content write lock");
+      }
+   }
+
+   public VirtualFile getDeploymentContent(String vfsPath, DeploymentPhase phase)
+         throws IOException
+   {
+      URI rootURI = this.getDeploymentURI(phase);
+      VirtualFile root = VFS.getRoot(rootURI);
+      VirtualFile content = root.getChild(vfsPath);
+      if(content == null)
+         throw new FileNotFoundException(vfsPath+" not found under root: "+rootURI);
+      return content;
+   }
+
+   public void lockDeploymentContent(String vfsPath, DeploymentPhase phase)
+   {
+      lockedApps.add(vfsPath);
+   }
+
+   public void unlockDeploymentContent(String vfsPath, DeploymentPhase phase)
+   {
+      lockedApps.remove(vfsPath);
+   }
+
+   public void acquireDeploymentContentLock()
+   {
+      contentLock.writeLock().lock();
+      if( log.isTraceEnabled() )
+         log.trace("acquireDeploymentContentLock, have write lock"); 
+   }
+   public void releaseDeploymentContentLock()
+   {
+      contentLock.writeLock().unlock();
+      if( log.isTraceEnabled() )
+         log.trace("releaseDeploymentContentLock, gave up write lock");       
+   }
+
+   public void addDeployment(String vfsPath, VFSDeployment d, DeploymentPhase phase)
+      throws Exception
+   {
+      switch( phase )
+      {
+         case BOOTSTRAP:
+            this.addBootstrap(vfsPath, d);
+            break;
+         case DEPLOYER:
+            this.addDeployer(vfsPath, d);
+            break;
+         case APPLICATION:
+            this.addApplication(vfsPath, d);
+            break;
+         case APPLICATION_TRANSIENT:
+            this.addApplication(vfsPath, d);
+            break;
+      }
+   }
+
+   public void updateDeployment(String vfsPath, VFSDeployment d, DeploymentPhase phase)
+      throws Exception
+   {
+   }
+   public VFSDeployment getDeployment(String name, DeploymentPhase phase)
+      throws Exception
+   {
+      VFSDeployment ctx = null;
+      if( phase == null )
+      {
+         try
+         {
+            if( ctx == null )
+               ctx = this.getApplication(name);
+         }
+         catch(Exception ignore)
+         {
+         }
+      }
+      else
+      {
+         switch( phase )
+         {
+            case BOOTSTRAP:
+               ctx = this.getBootstrap(name);
+               break;
+            case DEPLOYER:
+               break;
+            case APPLICATION:
+               ctx = this.getApplication(name);
+               break;
+         }
+      }
+      // Make sure we don't return null
+      if( ctx == null )
+         throw new Exception("name="+name+", phase="+phase);
+      return ctx;
+   }
+
+   public Collection<VFSDeployment> getDeployments()
+   {
+      HashSet<VFSDeployment> deployments = new HashSet<VFSDeployment>();
+      deployments.addAll(this.applicationCtxs.values());
+      return Collections.unmodifiableCollection(deployments);
+   }
+
+   /**
+    * Scan the applications for changes.
+    */
+   public synchronized Collection<ModificationInfo> getModifiedDeployments()
+      throws Exception
+   {
+      ArrayList<ModificationInfo> modified = new ArrayList<ModificationInfo>();
+      Collection<VFSDeployment> apps = getApplications();
+      boolean trace = log.isTraceEnabled();
+      if( trace )
+         log.trace("Checking applications for modifications");
+      if( trace )
+         log.trace("Aquiring content read lock");
+      contentLock.readLock().lock();
+      try
+      {
+         if( apps != null )
+         {
+            Iterator<VFSDeployment> iter = apps.iterator();
+            while( iter.hasNext() )
+            {
+               VFSDeployment ctx = iter.next();
+               VirtualFile root = ctx.getRoot();
+               // See if this file is locked
+               if(this.lockedApps.contains(root.getPathName()))
+               {
+                  if(trace)
+                     log.trace("Ignoring locked application: "+root);
+                  continue;
+               }
+               Long rootLastModified = root.getLastModified();
+               String name = root.getPathName();
+               // Check for removal
+               if( root.exists() == false )
+               {
+                  ModificationInfo info = new ModificationInfo(ctx, rootLastModified, ModifyStatus.REMOVED);
+                  modified.add(info);
+                  iter.remove();
+                  if( trace )
+                     log.trace(name+" was removed");
+               }
+               // Check for modification
+               else if( root.hasBeenModified() )
+               {
+                  if( trace )
+                     log.trace(name+" was modified: "+rootLastModified);
+                  // Need to create a duplicate ctx
+                  VFSDeployment ctx2 = loadDeploymentData(root);
+                  ModificationInfo info = new ModificationInfo(ctx2, rootLastModified, ModifyStatus.MODIFIED);
+                  modified.add(info);
+               }
+               // TODO: this could check metadata files modifications as well
+            }
+            // Now check for additions
+            for (File applicationDir : applicationDirs)
+            {
+               VirtualFile deployDir = VFS.getRoot(applicationDir.toURI());
+               List<VirtualFile> children = deployDir.getChildren();
+               for(VirtualFile vf : children)
+               {
+                  URI uri = vf.toURI();
+                  if( applicationCtxs.containsKey(uri.toString()) == false )
+                  {
+                     VFSDeployment ctx = loadDeploymentData(vf);
+                     ModificationInfo info = new ModificationInfo(ctx, vf.getLastModified(), ModifyStatus.ADDED);
+                     modified.add(info);
+                     applicationCtxs.put(vf.toURI().toString(), ctx);
+                  }
+               }
+            }
+         }
+      }
+      finally
+      {
+         contentLock.readLock().unlock();
+         if( trace )
+            log.trace("Released content read lock");
+      }
+
+      if(modified.size() > 0)
+         lastModified = System.currentTimeMillis();
+      return modified;
+   }
+
+   public Collection<VFSDeployment> getDeployments(DeploymentPhase phase)
+      throws Exception
+   {
+      Collection<VFSDeployment> ctxs = null;
+      switch( phase )
+      {
+         case BOOTSTRAP:
+            ctxs = this.getBootstraps();
+            break;
+         case DEPLOYER:
+            break;
+         case APPLICATION:
+            ctxs = this.getApplications();
+            break;
+      }
+      return ctxs;
+   }
+
+   public VFSDeployment removeDeployment(String name, DeploymentPhase phase)
+      throws Exception
+   {
+      VFSDeployment ctx = null;
+      switch( phase )
+      {
+         case BOOTSTRAP:
+            ctx = this.removeBootstrap(name);
+            break;
+         case DEPLOYER:
+            ctx = this.removeDeployer(name);
+            break;
+         case APPLICATION:
+            ctx = this.removeApplication(name);
+            break;
+      }
+      return ctx;
+   }
+   public String toString()
+   {
+      StringBuilder tmp = new StringBuilder(super.toString());
+      tmp.append("(root=");
+      tmp.append(root);
+      tmp.append(")");
+      return tmp.toString();
+   }
+
+   /**
+    * Create a profile deployment repository
+    * 
+    * @throws IOException
+    */
+   public void create() throws Exception
+   {
+      File profileRoot = root;
+
+      // server/{name}/deploy
+      for (File applicationDir : applicationDirs)
+      {
+         if(applicationDir.exists() == true)
+            continue;
+         if( applicationDir.mkdirs() == false )
+            throw new IOException("Failed to create profile deploy dir: "+applicationDir);
+      }
+   }
+
+   /**
+    * Load the profile deployments
+    * 
+    * @throws IOException
+    * @throws NoSuchProfileException
+    */
+   public void load() throws Exception
+   {
+      File profileRoot = root;
+      if( profileRoot.exists() == false )
+         throw new Exception("Profile root does not exists: "+profileRoot);
+
+      // server/{name}/deploy
+      for (File applicationDir : applicationDirs)
+      {
+         if( applicationDir.exists() == false )
+            throw new FileNotFoundException("Profile contains no deploy dir: "+applicationDir);
+      }
+
+      for (File applicationDir : applicationDirs)
+      {
+         VFS deployVFS = VFS.getVFS(applicationDir.toURI());
+         loadApplications(deployVFS.getRoot());
+      }
+      this.lastModified = System.currentTimeMillis();
+   }
+
+   /**
+    * Remove the contents of the profile repository
+    * @throws IOException
+    * @throws NoSuchProfileException
+    */
+   public void remove() throws IOException
+   {
+      File profileRoot = root;
+      Files.delete(profileRoot);
+   }
+
+   protected void addBootstrap(String vfsPath, VFSDeployment ctx)
+      throws Exception
+   {
+   }
+
+
+   protected void addDeployer(String vfsPath, VFSDeployment ctx)
+      throws Exception
+   {
+   }
+
+   protected void addApplication(String vfsPath, VFSDeployment ctx)
+      throws Exception
+   {
+      this.applicationCtxs.put(vfsPath, ctx);
+   }
+
+   protected VFSDeployment getBootstrap(String vfsPath)
+      throws Exception
+   {
+      VFSDeployment ctx = null;
+      return ctx;
+   }
+
+   protected Collection<VFSDeployment> getBootstraps()
+      throws Exception
+   {
+      Collection<VFSDeployment> ctxs = null;
+      return ctxs;
+   }
+
+   protected URI getPhaseURI(DeploymentPhase phase)
+   {
+      URI uri = null;
+      switch( phase )
+      {
+         case BOOTSTRAP:
+            uri = getBootstrapURI();
+            break;
+         case DEPLOYER:
+            break;
+         case APPLICATION:
+            uri = getApplicationURI();
+            break;
+         case APPLICATION_TRANSIENT:
+            // TODO
+            break;
+      }
+      return uri;
+   }
+
+   protected File getPhaseDir(DeploymentPhase phase)
+   {
+      File dir = null;
+      switch( phase )
+      {
+         case BOOTSTRAP:
+            break;
+         case DEPLOYER:
+            break;
+         case APPLICATION:
+            dir = applicationDirs[0];
+            break;
+         case APPLICATION_TRANSIENT:
+            // TODO
+            break;
+      }
+      return dir;
+   }
+
+   protected URI getBootstrapURI()
+   {
+      return null;
+   }
+   protected URI getApplicationURI()
+   {
+      File applicationDir = applicationDirs[0];
+      return applicationDir.toURI();
+   }
+
+   protected VFSDeployment getApplication(String vfsPath)
+      throws Exception
+   {
+      VFSDeployment ctx = applicationCtxs.get(vfsPath);
+      if( ctx == null )
+      {
+         // Try to find the simple name
+         log.debug("Failed to find application for: "+vfsPath+", scanning for simple name");
+         for(VFSDeployment deployment : applicationCtxs.values())
+         {
+            log.info("Checking: "+deployment.getSimpleName());
+            if(deployment.getSimpleName().equals(vfsPath))
+            {
+               log.debug("Matched to simple name of deployment:"+deployment);
+               ctx = deployment;
+               break;
+            }
+         }
+         if(ctx == null)
+            throw new Exception(vfsPath);
+      }
+      return ctx;
+   }
+
+   protected Collection<VFSDeployment> getApplications()
+      throws Exception
+   {
+      return applicationCtxs.values();
+   }
+
+   protected VFSDeployment removeBootstrap(String vfsPath) throws IOException
+   {
+      VFSDeployment vfsDeployment = null;
+      return vfsDeployment;
+   }
+
+   // this is an infinite loop
+   protected VFSDeployment removeDeployer(String vfsPath) throws IOException
+   {
+      VFSDeployment vfsDeployment = null;
+      return vfsDeployment;
+   }
+   protected VFSDeployment removeApplication(String vfsPath) throws IOException
+   {
+      VFSDeployment vfsDeployment = applicationCtxs.get(vfsPath);
+      if(vfsDeployment == null)
+         throw new IllegalStateException("Deployment not found: " + vfsPath);
+      // Find the application dir
+      File applicationDir = applicationDirs[0];
+      File deploymentFile = new File(applicationDir, vfsDeployment.getSimpleName());
+      if( Files.delete(deploymentFile) == false )
+         throw new IOException("Failed to delete: "+deploymentFile);
+      return this.applicationCtxs.remove(vfsPath);
+   }
+   protected void setBootstrapURI(URI uri)
+   {
+   }
+   protected void setDeployersURI(URI uri)
+   {
+   }
+
+   /**
+    * Load all the applications under the applicationDir.
+    * 
+    * @param applicationDir
+    * @throws IOException
+    */
+   private void loadApplications(VirtualFile applicationDir)
+      throws IOException
+   {
+      List<VirtualFile> children = applicationDir.getChildren();
+      for(VirtualFile vf : children)
+      {
+         VFSDeployment vfCtx = loadDeploymentData(vf);
+         applicationCtxs.put(vfCtx.getName(), vfCtx);         
+      }
+   }
+
+   /**
+    * TODO: this could be dropped since the serialize aspect loads the data
+    * @param file
+    * @return the deployment
+    */
+   private VFSDeployment loadDeploymentData(VirtualFile file)
+   {
+      // Check for a persisted context
+      // Load the base deployment
+      VFSDeployment deployment = VFSDeploymentFactory.getInstance().createVFSDeployment(file);
+      log.debug("Created deployment: "+deployment);
+      return deployment;
+   }
+
+}

Added: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/ModificationInfo.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/ModificationInfo.java	                        (rev 0)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/ModificationInfo.java	2008-06-20 14:04:12 UTC (rev 74877)
@@ -0,0 +1,69 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.virtual.support.ps;
+
+import java.io.Serializable;
+
+import org.jboss.test.virtual.support.ps.VFSDeployment;
+
+/**
+ * Represents a modified deployment returned from the modified deployments scan.
+ *  
+ * @see Profile#getModifiedDeployments()
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author adrian at jboss.org
+ * @version $Revision: 63730 $
+ */
+public class ModificationInfo implements Serializable
+{
+   private final static long serialVersionUID = 1;
+
+   public enum ModifyStatus {ADDED, MODIFIED, REMOVED};
+   private VFSDeployment deployment;
+   private long lastModified;
+   private ModifyStatus status;
+
+   public ModificationInfo(VFSDeployment deployment, long lastModified, ModifyStatus status)
+   {
+      this.deployment = deployment;
+      this.lastModified = lastModified;
+      this.status = status;
+   }
+
+   public VFSDeployment getDeployment()
+   {
+      return deployment;
+   }
+
+   public long getLastModified()
+   {
+      return lastModified;
+   }
+
+   public ModifyStatus getStatus()
+   {
+      return status;
+   }
+
+}
+

Added: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/VFSDeployment.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/VFSDeployment.java	                        (rev 0)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/VFSDeployment.java	2008-06-20 14:04:12 UTC (rev 74877)
@@ -0,0 +1,35 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.virtual.support.ps;
+
+import org.jboss.virtual.VirtualFile;
+
+/**
+ * @author Scott.Stark at jboss.org
+ * @version $Revision:$
+ */
+public interface VFSDeployment
+{
+   public String getName();
+   public String getSimpleName();
+   public VirtualFile getRoot();
+}

Added: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/VFSDeploymentFactory.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/VFSDeploymentFactory.java	                        (rev 0)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/VFSDeploymentFactory.java	2008-06-20 14:04:12 UTC (rev 74877)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.virtual.support.ps;
+
+import org.jboss.virtual.VirtualFile;
+
+/**
+ * @author Scott.Stark at jboss.org
+ * @version $Revision:$
+ */
+public class VFSDeploymentFactory
+{
+   private static VFSDeploymentFactory instance = new VFSDeploymentFactory();
+
+   public static VFSDeploymentFactory getInstance()
+   {
+      return instance;
+   }
+
+   public VFSDeployment createVFSDeployment(VirtualFile file)
+   {
+      return new VFSDeploymentImpl(file);
+   }
+
+}

Added: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/VFSDeploymentImpl.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/VFSDeploymentImpl.java	                        (rev 0)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/VFSDeploymentImpl.java	2008-06-20 14:04:12 UTC (rev 74877)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.virtual.support.ps;
+
+import org.jboss.virtual.VirtualFile;
+
+/**
+ * @author Scott.Stark at jboss.org
+ * @version $Revision:$
+ */
+public class VFSDeploymentImpl
+   implements VFSDeployment
+{
+   private VirtualFile root;
+
+   public VFSDeploymentImpl(VirtualFile root)
+   {
+      this.root = root;
+   }
+
+   public VirtualFile getRoot()
+   {
+      return root;
+   }
+
+   public String getName()
+   {
+      return root.getName();
+   }
+
+   public String getSimpleName()
+   {
+      return root.getPathName();
+   }
+
+}

Added: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/hotdeploy/HDScanner.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/hotdeploy/HDScanner.java	                        (rev 0)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/ps/hotdeploy/HDScanner.java	2008-06-20 14:04:12 UTC (rev 74877)
@@ -0,0 +1,261 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.virtual.support.ps.hotdeploy;
+
+import java.util.Collection;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+import org.jboss.logging.Logger;
+import org.jboss.test.virtual.support.ps.MockProfileServiceRepository;
+import org.jboss.test.virtual.support.ps.ModificationInfo;
+import org.jboss.test.virtual.support.ps.VFSDeployment;
+
+/**
+ * A DeploymentScanner built on the ProfileService and MainDeployer. This
+ * is really just a simple ExecutorService Runnable that knows nothing
+ * about how to detect changed deployers. The ProfileService determines
+ * this.
+ * 
+ * @see MainDeployer
+ * @see ProfileService
+ * 
+ * @author <a href="mailto:dimitris at jboss.org">Dimitris Andreadis</a>
+ * @author Scott.Stark at jboss.org
+ * @author adrian at jboss.org
+ * @version $Revision: 64997 $
+ */
+public class HDScanner
+   implements Runnable
+{
+   private static final Logger log = Logger.getLogger(HDScanner.class);
+   // Private Data --------------------------------------------------
+
+   /** The ProfileService used to determine modified deployments */
+   private MockProfileServiceRepository profileService;
+
+   /** The ExecutorService/ThreadPool for performing scans */
+   private ScheduledExecutorService scanExecutor;
+   private ScheduledFuture activeScan;
+   /** Thread name used when the ScheduledExecutorService is created internally */
+   private String scanThreadName = "HDScanner";
+
+   /** Period in ms between deployment scans */
+   private long scanPeriod = 5000;
+   /** The number of scans that have been done */
+   private int scanCount;
+   private boolean skipScan;
+
+   // Constructor ---------------------------------------------------
+   
+   public HDScanner()
+   {
+      // empty
+   }
+   
+   // Attributes ----------------------------------------------------
+
+   public MockProfileServiceRepository getProfileService()
+   {
+      return profileService;
+   }
+   public void setProfileService(MockProfileServiceRepository profileService)
+   {
+      this.profileService = profileService;
+   }
+
+   /**
+    * @return Returns the scanExecutor.
+    */
+   public ScheduledExecutorService getScanExecutor()
+   {
+      return this.scanExecutor;
+   }
+
+   /**
+    * @param scanExecutor The scanExecutor to set.
+    */
+   public void setScanExecutor(ScheduledExecutorService scanExecutor)
+   {
+      this.scanExecutor = scanExecutor;
+   }
+
+   public String getScanThreadName()
+   {
+      return scanThreadName;
+   }
+
+   public void setScanThreadName(String scanThreadName)
+   {
+      this.scanThreadName = scanThreadName;
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.deployment.scanner.VFSDeploymentScanner#getScanPeriod()
+    */
+   public long getScanPeriod()
+   {
+      return scanPeriod;
+   }
+   /* (non-Javadoc)
+    * @see org.jboss.deployment.scanner.VFSDeploymentScanner#setScanPeriod(long)
+    */
+   public void setScanPeriod(long period)
+   {
+      this.scanPeriod = period;
+   }
+
+   /** 
+    * Are deployment scans enabled.
+    * 
+    * @return whether scan is enabled
+    */
+   public boolean isScanEnabled()
+   {
+      return activeScan != null;
+   }
+
+   
+   public synchronized boolean isSkipScan()
+   {
+      return skipScan;
+   }
+
+   public synchronized void setSkipScan(boolean skipScan)
+   {
+      this.skipScan = skipScan;
+   }
+
+   public synchronized int getScanCount()
+   {
+      return scanCount;
+   }
+   public synchronized void resetScanCount()
+   {
+      this.scanCount = 0;
+   }
+
+   /**
+    * Enable/disable deployment scans.
+    * @param scanEnabled true to enable scans, false to disable.
+    */
+   public synchronized void setScanEnabled(boolean scanEnabled)
+   {
+      if( scanEnabled == true && activeScan == null )
+      {
+         activeScan = this.scanExecutor.scheduleWithFixedDelay(this, 0,
+               scanPeriod, TimeUnit.MILLISECONDS);
+      }
+      else if( scanEnabled == false && activeScan != null )
+      {
+         activeScan.cancel(true);
+         activeScan = null;
+      }
+   }
+
+
+   // Operations ----------------------------------------------------
+   
+   public void start() throws Exception
+   {
+      // Default to a single thread executor
+      if( scanExecutor == null )
+      {
+         scanExecutor = Executors.newSingleThreadScheduledExecutor(
+            new ThreadFactory()
+            {
+               public Thread newThread(Runnable r)
+               {
+                  return new Thread(r, HDScanner.this.getScanThreadName());
+               }
+            }
+        );
+      }
+      activeScan = scanExecutor.scheduleWithFixedDelay(this, 0,
+            scanPeriod, TimeUnit.MILLISECONDS);
+   }
+
+   /**
+    * Executes scan 
+    *
+    */
+   public void run()
+   {
+      try
+      {
+         scan();
+      }
+      catch(Throwable e)
+      {
+         log.warn("Scan failed", e);
+      }
+      finally
+      {
+         incScanCount();
+      }
+   }
+
+   public void stop()
+   {
+      if( activeScan != null )
+      {
+         activeScan.cancel(true);
+         activeScan = null;
+      }
+   }
+
+   public synchronized void scan() throws Exception
+   {
+      if(isSkipScan())
+         return;
+
+      // Query the ProfileService for deployments
+      log.debug("Begin deployment scan");
+
+      
+      // Get the modified deployments
+      Collection<ModificationInfo> modified  = profileService.getModifiedDeployments();
+      for(ModificationInfo info : modified)
+      {
+         VFSDeployment ctx = info.getDeployment();
+         log.debug("Saw modified ctx: "+ctx.getName());
+         // TODO: cause the file to be opened/closed?
+      }
+      log.debug("End deployment scan");
+   }
+
+   /**
+    * Inc the scanCount and to a notifyAll.
+    *
+    */
+   protected synchronized void incScanCount()
+   {
+      scanCount ++;
+      notifyAll();
+   }
+
+   // Private -------------------------------------------------------
+
+}

Added: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/HDScannerTestCase.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/HDScannerTestCase.java	                        (rev 0)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/HDScannerTestCase.java	2008-06-20 14:04:12 UTC (rev 74877)
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.virtual.test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.net.URI;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+
+import org.jboss.test.virtual.support.ps.DeploymentPhase;
+import org.jboss.test.virtual.support.ps.MockProfileServiceRepository;
+import org.jboss.test.virtual.support.ps.VFSDeployment;
+import org.jboss.test.virtual.support.ps.VFSDeploymentFactory;
+import org.jboss.test.virtual.support.ps.hotdeploy.HDScanner;
+import org.jboss.virtual.VFS;
+import org.jboss.virtual.VirtualFile;
+
+/**
+ * @author Scott.Stark at jboss.org
+ * @version $Revision:$
+ */
+public class HDScannerTestCase extends OSAwareVFSTest
+{
+
+   public HDScannerTestCase(String name, boolean forceCopy)
+   {
+      super(name, forceCopy);
+   }
+
+   public HDScannerTestCase(String name)
+   {
+      super(name);
+   }
+
+   public void testDeleteWhileScanning()
+      throws Exception
+   {
+      // Create a root in the system tmp dir
+      File root = File.createTempFile("testDeleteWhileScanning", ".root");
+      root.delete();
+      assertTrue(root.mkdir());
+      getLog().info("Created root dir: "+root);
+      File deployDir = new File(root, "deploy");
+      assertTrue(deployDir.mkdir());
+      // Remove any existing content
+      for(File f : deployDir.listFiles())
+         f.delete();
+
+      URI[] appURIs = {deployDir.toURI()};
+      MockProfileServiceRepository repository = new MockProfileServiceRepository(root, appURIs);
+      HDScanner scanner = new HDScanner();
+      scanner.setProfileService(repository);
+      scanner.setScanPeriod(1000);
+
+      VFS vfs = VFS.getVFS(root.toURI());
+      File archive = generateArchive(deployDir);
+      VirtualFile archiveVF = vfs.getChild("deploy/"+archive.getName());      
+      VFSDeployment vfsd = VFSDeploymentFactory.getInstance().createVFSDeployment(archiveVF);
+      repository.addDeployment(archiveVF.toURI().toString(), vfsd, DeploymentPhase.APPLICATION);
+
+      getLog().debug("Waiting for 10 scans...");
+      scanner.start();
+      while(scanner.getScanCount() < 10)
+      {
+         Thread.sleep(1000);
+         // Update the archive last modifed time
+         archive.setLastModified(System.currentTimeMillis());
+      }
+      getLog().info("Trying to remove: "+archive.getAbsolutePath());
+      assertTrue(archive.delete());
+      getLog().info("Deleted deployed archive");
+      scanner.stop();
+   }
+
+   protected File generateArchive(File deployDir)
+      throws Exception
+   {
+      File tmpJar = File.createTempFile("archive", ".jar", deployDir);
+      FileOutputStream fos = new FileOutputStream(tmpJar);
+      JarOutputStream jos = new JarOutputStream(fos);
+      jos.setLevel(5);
+      jos.setComment(tmpJar.getName());
+      JarEntry je = new JarEntry("META-INF/");
+      je.setComment("META-INF directory");
+      je.setTime(System.currentTimeMillis());
+      jos.putNextEntry(je);
+      je = new JarEntry("META-INF/metadata.xml");
+      StringBuffer contents = new StringBuffer();
+      contents.append("<metadata name='"+tmpJar.getName()+"'/>");
+      je.setSize(contents.length());
+      je.setTime(System.currentTimeMillis()+1);
+      je.setMethod(JarEntry.DEFLATED);
+      jos.putNextEntry(je);
+      jos.write(contents.toString().getBytes());
+      jos.closeEntry();
+      jos.close();
+      fos.close();
+      assertTrue(tmpJar.exists());
+      return tmpJar;
+   }
+}




More information about the jboss-cvs-commits mailing list