Author: ccustine
Date: Tue Feb  5 22:24:32 2008
New Revision: 618908

URL: http://svn.apache.org/viewvc?rev=618908&view=rev
Log:
SM-607 Files dropped into the install directory sometimes result in a "file in 
use by another process" error 
SM-1217 Deployment fails with ZipException

Modified:
    
servicemix/smx3/trunk/core/servicemix-core/src/main/java/org/apache/servicemix/jbi/framework/AutoDeploymentService.java
    
servicemix/smx3/trunk/core/servicemix-core/src/test/java/org/apache/servicemix/jbi/installation/HotDeployTest.java

Modified: 
servicemix/smx3/trunk/core/servicemix-core/src/main/java/org/apache/servicemix/jbi/framework/AutoDeploymentService.java
URL: 
http://svn.apache.org/viewvc/servicemix/smx3/trunk/core/servicemix-core/src/main/java/org/apache/servicemix/jbi/framework/AutoDeploymentService.java?rev=618908&r1=618907&r2=618908&view=diff
==============================================================================
--- 
servicemix/smx3/trunk/core/servicemix-core/src/main/java/org/apache/servicemix/jbi/framework/AutoDeploymentService.java
 (original)
+++ 
servicemix/smx3/trunk/core/servicemix-core/src/main/java/org/apache/servicemix/jbi/framework/AutoDeploymentService.java
 Tue Feb  5 22:24:32 2008
@@ -16,8 +16,7 @@
  */
 package org.apache.servicemix.jbi.framework;
 
-import java.io.File;
-import java.io.IOException;
+import java.io.*;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
@@ -29,6 +28,7 @@
 import java.util.Set;
 import java.util.Timer;
 import java.util.TimerTask;
+import java.util.zip.ZipFile;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -635,7 +635,7 @@
                 for (int i = 0; i < files.length; i++) {
                     final File file = files[i];
                     tmpList.add(file.getName());
-                    if (isAllowedExtension(file.getName())) {
+                    if (isAllowedExtension(file.getName()) && 
isAvailable(file)) {
                         ArchiveEntry lastEntry = fileMap.get(file.getName());
                         if (lastEntry == null || file.lastModified() > 
lastEntry.lastModified.getTime()) {
                             try {
@@ -672,6 +672,34 @@
                 persistState(root, fileMap);
             }
         }
+    }
+
+    private boolean isAvailable(File file) {
+        // First check to see if the file is still growing
+        long targetLength = file.length();
+        try {
+            Thread.sleep(100);
+        } catch (InterruptedException e) {
+            //Do nothing
+        }
+        long target2Length = file.length();
+
+        if (targetLength != target2Length) {
+            LOG.warn("File is still being copied, deployment deferred to next 
cycle: " + file.getName());
+            return false;
+        }
+
+        // If file size is consistent, do a foolproof check of the zip file
+        try {
+            ZipFile zip = new ZipFile(file);
+            zip.size();
+            zip.close();
+        } catch (IOException e) {
+            LOG.warn("Unable to open deployment file, deployment deferred to 
next cycle: " + file.getName());
+            return false;
+        }
+
+        return true;
     }
 
     private boolean isAllowedExtension(String file) {

Modified: 
servicemix/smx3/trunk/core/servicemix-core/src/test/java/org/apache/servicemix/jbi/installation/HotDeployTest.java
URL: 
http://svn.apache.org/viewvc/servicemix/smx3/trunk/core/servicemix-core/src/test/java/org/apache/servicemix/jbi/installation/HotDeployTest.java?rev=618908&r1=618907&r2=618908&view=diff
==============================================================================
--- 
servicemix/smx3/trunk/core/servicemix-core/src/test/java/org/apache/servicemix/jbi/installation/HotDeployTest.java
 (original)
+++ 
servicemix/smx3/trunk/core/servicemix-core/src/test/java/org/apache/servicemix/jbi/installation/HotDeployTest.java
 Tue Feb  5 22:24:32 2008
@@ -16,9 +16,7 @@
  */
 package org.apache.servicemix.jbi.installation;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
+import java.io.*;
 
 import javax.jbi.JBIException;
 import javax.jbi.component.Bootstrap;
@@ -92,6 +90,88 @@
         container.setMonitorInstallationDirectory(true);
         container.setMonitorDeploymentDirectory(true);
         container.setMonitorInterval(1);
+    }
+
+    /**
+     * Simulate a slow copy or a large file deployment by copying small chinks 
of the file at a time.
+     * 
+     * @param in
+     * @param out
+     * @throws IOException
+     */
+    private static void slowCopyInputStream(InputStream in, OutputStream out) 
throws IOException {
+        byte[] buffer = new byte[1];
+        int len = in.read(buffer);
+        while (len >= 0) {
+            try {
+                Thread.sleep(10) ;
+            } catch (InterruptedException e) {
+                // Do nothing
+            }
+            out.write(buffer, 0, len);
+            len = in.read(buffer);
+        }
+        in.close();
+        out.close();
+    }
+
+    /**
+     * Test a slow copy or similar type of file copy such as scp or ftp remote 
upload.
+     * 
+     * @throws Exception
+     */
+
+    public void testHotDeploySlowCopy() throws Exception {
+        final Object lock = new Object();
+        // configure mocks
+        Bootstrap1.setDelegate(new BootstrapDelegate(bootstrap) {
+            public void cleanUp() throws JBIException {
+                super.cleanUp();
+                synchronized (lock) {
+                    lock.notify();
+                }
+            }
+        });
+        reset();
+        bootstrap.init(null);
+        bootstrapMock.setMatcher(MockControl.ALWAYS_MATCHER);
+        bootstrap.getExtensionMBeanName();
+        bootstrapMock.setReturnValue(null);
+        bootstrap.onInstall();
+        bootstrap.cleanUp();
+        component.getLifeCycle();
+        componentMock.setReturnValue(lifecycle);
+        lifecycle.init(null);
+        lifecycleMock.setMatcher(MockControl.ALWAYS_MATCHER);
+        lifecycle.start();
+        replay();
+        // test component installation
+        startContainer(true);
+        String installJarUrl = 
createInstallerArchive("component1").getAbsolutePath();
+        File hdInstaller = new 
File(container.getEnvironmentContext().getInstallationDir(), new 
File(installJarUrl).getName());
+
+        synchronized (lock) {
+            slowCopyInputStream(new FileInputStream(installJarUrl), new 
FileOutputStream(hdInstaller));
+            lock.wait(5000);
+        }
+        Thread.sleep(50);
+
+        ObjectName lifecycleName = 
container.getComponent("component1").getMBeanName();
+        assertNotNull(lifecycleName);
+        LifeCycleMBean lifecycleMBean = (LifeCycleMBean) 
MBeanServerInvocationHandler.newProxyInstance(container.getMBeanServer(),
+                        lifecycleName, LifeCycleMBean.class, false);
+        assertEquals(LifeCycleMBean.STARTED, lifecycleMBean.getCurrentState());
+        // check mocks
+        verify();
+
+        // Clean shutdown
+        reset();
+        component.getLifeCycle();
+        componentMock.setReturnValue(lifecycle);
+        lifecycle.stop();
+        lifecycle.shutDown();
+        replay();
+        shutdownContainer();
     }
 
     public void testHotDeployComponent() throws Exception {


Reply via email to