Author: ccustine
Date: Tue Feb 5 22:02:47 2008
New Revision: 618904
URL: http://svn.apache.org/viewvc?rev=618904&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/branches/servicemix-3.2/core/servicemix-core/src/main/java/org/apache/servicemix/jbi/framework/AutoDeploymentService.java
servicemix/smx3/branches/servicemix-3.2/core/servicemix-core/src/test/java/org/apache/servicemix/jbi/installation/HotDeployTest.java
Modified:
servicemix/smx3/branches/servicemix-3.2/core/servicemix-core/src/main/java/org/apache/servicemix/jbi/framework/AutoDeploymentService.java
URL:
http://svn.apache.org/viewvc/servicemix/smx3/branches/servicemix-3.2/core/servicemix-core/src/main/java/org/apache/servicemix/jbi/framework/AutoDeploymentService.java?rev=618904&r1=618903&r2=618904&view=diff
==============================================================================
---
servicemix/smx3/branches/servicemix-3.2/core/servicemix-core/src/main/java/org/apache/servicemix/jbi/framework/AutoDeploymentService.java
(original)
+++
servicemix/smx3/branches/servicemix-3.2/core/servicemix-core/src/main/java/org/apache/servicemix/jbi/framework/AutoDeploymentService.java
Tue Feb 5 22:02:47 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/branches/servicemix-3.2/core/servicemix-core/src/test/java/org/apache/servicemix/jbi/installation/HotDeployTest.java
URL:
http://svn.apache.org/viewvc/servicemix/smx3/branches/servicemix-3.2/core/servicemix-core/src/test/java/org/apache/servicemix/jbi/installation/HotDeployTest.java?rev=618904&r1=618903&r2=618904&view=diff
==============================================================================
---
servicemix/smx3/branches/servicemix-3.2/core/servicemix-core/src/test/java/org/apache/servicemix/jbi/installation/HotDeployTest.java
(original)
+++
servicemix/smx3/branches/servicemix-3.2/core/servicemix-core/src/test/java/org/apache/servicemix/jbi/installation/HotDeployTest.java
Tue Feb 5 22:02:47 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 {