From 70bbea19659d1a8dd693d2250cee85a83626c31f Mon Sep 17 00:00:00 2001
From: brinn <brinn>
Date: Fri, 30 Nov 2007 10:21:54 +0000
Subject: [PATCH] merged from branch datamover/1.0.x, r2792 change: check
 availability of destination directory; this catches a case where the
 automounter makes available a remote target with delay only and the first
 stat() call fails

SVN: 2868
---
 .../ch/systemsx/cisd/datamover/SelfTest.java  |  4 +++-
 .../datamover/filesystem/intf/FileStore.java  |  8 ++++---
 .../filesystem/remote/RemotePathMover.java    | 21 +++++++++++++++++--
 .../filesystem/store/FileStoreLocal.java      | 10 +++++++--
 .../filesystem/store/FileStoreRemote.java     |  2 +-
 .../store/FileStoreRemoteMounted.java         |  4 ++--
 .../remote/CopyActivityMonitorTest.java       |  7 +++----
 7 files changed, 41 insertions(+), 15 deletions(-)

diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/SelfTest.java b/datamover/source/java/ch/systemsx/cisd/datamover/SelfTest.java
index 3159930379b..b3e45e1d1b9 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/SelfTest.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/SelfTest.java
@@ -34,6 +34,8 @@ import ch.systemsx.cisd.datamover.filesystem.intf.IPathCopier;
  */
 public class SelfTest
 {
+    private static final long TIMEOUT_MILLIS = 3000L;
+
     private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, SelfTest.class);
 
     static
@@ -48,7 +50,7 @@ public class SelfTest
         checkPathRecordsContainEachOther(pathRecords);
         for (FileStore pathRecord : pathRecords)
         {
-            String errorMessage = pathRecord.tryCheckDirectoryFullyAccessible();
+            String errorMessage = pathRecord.tryCheckDirectoryFullyAccessible(TIMEOUT_MILLIS);
             if (errorMessage != null)
             {
                 throw new ConfigurationFailureException(errorMessage);
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/FileStore.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/FileStore.java
index 2a741df2978..610bb2ee2c1 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/FileStore.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/intf/FileStore.java
@@ -165,16 +165,18 @@ public abstract class FileStore
     /**
      * Checks whether this store is a directory and is fully accessible to the program.
      * 
+     * @param timeOutMillis The time (in milli-seconds) to wait for the target to become available if it is not
+     *            initially.
      * @return <code>null</code> if the <var>directory</var> is fully accessible and an error message describing the
      *         problem with the <var>directory</var> otherwise.
      */
-    public abstract String tryCheckDirectoryFullyAccessible();
+    public abstract String tryCheckDirectoryFullyAccessible(final long timeOutMillis);
 
     public abstract boolean exists(StoreItem item);
 
     /**
      * Returns the last time when there was a write access to <var>item</var>.
-     *
+     * 
      * @param item The {@link StoreItem} to check.
      * @param stopWhenFindYounger If &gt; 0, the recursive search for younger file will be stopped when a file or
      *            directory is found that is as young as or younger than the time specified in this parameter.
@@ -183,7 +185,7 @@ public abstract class FileStore
     public abstract long lastChanged(StoreItem item, long stopWhenFindYounger);
 
     /**
-     * List files in the scanned store. Sort in order of "oldest first".  
+     * List files in the scanned store. Sort in order of "oldest first".
      */
     public abstract StoreItem[] tryListSortByLastModified(ISimpleLogger loggerOrNull);
 
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/remote/RemotePathMover.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/remote/RemotePathMover.java
index 120daaebb78..896e6fa2f0b 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/remote/RemotePathMover.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/remote/RemotePathMover.java
@@ -39,6 +39,8 @@ import ch.systemsx.cisd.datamover.intf.ITimingParameters;
 public final class RemotePathMover implements IStoreHandler
 {
 
+    private static final long TIMEOUT_DESTINATION_MILLIS = 3000L;
+
     private static final String START_COPYING_PATH_TEMPLATE = "Start copying path '%s' to '%s'.";
 
     private static final String START_COPYING_PATH_RETRY_TEMPLATE = "Start copying path '%s' to '%s' [retry: %d].";
@@ -93,8 +95,8 @@ public final class RemotePathMover implements IStoreHandler
         assert destinationDirectory != null;
         assert monitor != null;
         assert timingParameters != null;
-        String errorMsg = destinationDirectory.tryCheckDirectoryFullyAccessible();
-        assert errorMsg == null : errorMsg;
+        String errorMsg;
+        assert (errorMsg = destinationDirectory.tryCheckDirectoryFullyAccessible(TIMEOUT_DESTINATION_MILLIS)) == null : errorMsg;
         assert sourceDirectory.tryAsExtended() != null || destinationDirectory.tryAsExtended() != null;
 
         this.sourceDirectory = sourceDirectory;
@@ -137,6 +139,10 @@ public final class RemotePathMover implements IStoreHandler
                             .format(START_COPYING_PATH_TEMPLATE, getSrcPath(item), destinationDirectory));
                 }
             }
+            if (checkTargetAvailable() == false)
+            {
+                return;
+            }
             final long startTime = System.currentTimeMillis();
             final Status copyStatus = copyAndMonitor(item);
             if (StatusFlag.OK.equals(copyStatus.getFlag()))
@@ -191,6 +197,17 @@ public final class RemotePathMover implements IStoreHandler
         markAsFinished(item);
     }
 
+    private boolean checkTargetAvailable()
+    {
+        final String msg = destinationDirectory.tryCheckDirectoryFullyAccessible(TIMEOUT_DESTINATION_MILLIS);
+        if (msg != null)
+        {
+            machineLog.error(msg);
+            return false;
+        }
+        return true;
+    }
+
     private void remove(StoreItem sourceItem)
     {
         final StoreItem removalInProgressMarkerFile = tryMarkAsDeletionInProgress(sourceItem);
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreLocal.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreLocal.java
index 29a3aa290f7..25a28d47d0f 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreLocal.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreLocal.java
@@ -72,9 +72,15 @@ public class FileStoreLocal extends ExtendedFileStore
     }
 
     @Override
-    public String tryCheckDirectoryFullyAccessible()
+    public String tryCheckDirectoryFullyAccessible(final long timeOutMillis)
     {
-        return FileUtilities.checkDirectoryFullyAccessible(super.getPath(), super.getDescription());
+        final boolean available = FileUtilities.isAvailable(getPath(), timeOutMillis);
+        if (available == false)
+        {
+            return String.format("Path '%s' which is supposed to be a %s directory is not available.", getPath(),
+                    getDescription());
+        }
+        return FileUtilities.checkDirectoryFullyAccessible(getPath(), getDescription());
     }
 
     @Override
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemote.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemote.java
index 493e268862e..89c8533bcfb 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemote.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemote.java
@@ -69,7 +69,7 @@ public class FileStoreRemote extends FileStore
     }
 
     @Override
-    public String tryCheckDirectoryFullyAccessible()
+    public String tryCheckDirectoryFullyAccessible(final long timeOutMillis)
     {
         // TODO 2007-10-09, Tomasz Pylak: implement ssh tunneling mode. E.g. check if directory exists
         return null;
diff --git a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMounted.java b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMounted.java
index 25476145f2a..5cd3e48ee16 100644
--- a/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMounted.java
+++ b/datamover/source/java/ch/systemsx/cisd/datamover/filesystem/store/FileStoreRemoteMounted.java
@@ -83,9 +83,9 @@ public class FileStoreRemoteMounted extends FileStore
     }
 
     @Override
-    public String tryCheckDirectoryFullyAccessible()
+    public String tryCheckDirectoryFullyAccessible(final long timeOutMillis)
     {
-        return localImpl.tryCheckDirectoryFullyAccessible();
+        return localImpl.tryCheckDirectoryFullyAccessible(timeOutMillis);
     }
 
     @Override
diff --git a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/remote/CopyActivityMonitorTest.java b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/remote/CopyActivityMonitorTest.java
index 2581be93f0a..472c7701b6f 100644
--- a/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/remote/CopyActivityMonitorTest.java
+++ b/datamover/sourceTest/java/ch/systemsx/cisd/datamover/filesystem/remote/CopyActivityMonitorTest.java
@@ -167,9 +167,9 @@ public class CopyActivityMonitorTest
                 }
 
                 @Override
-                public String tryCheckDirectoryFullyAccessible()
+                public String tryCheckDirectoryFullyAccessible(long timeOutMillis)
                 {
-                    return localImpl.tryCheckDirectoryFullyAccessible();
+                    return localImpl.tryCheckDirectoryFullyAccessible(timeOutMillis);
                 }
 
                 @Override
@@ -341,8 +341,7 @@ public class CopyActivityMonitorTest
         LogMonitoringAppender appender =
                 LogMonitoringAppender.addAppender(LogCategory.OPERATION, "got stuck, starting a new one");
         final PathLastChangedCheckerDelayed checker =
-                new PathLastChangedCheckerDelayed(INACTIVITY_PERIOD_MILLIS,
-                        (long) (INACTIVITY_PERIOD_MILLIS / 10 * 1.5));
+                new PathLastChangedCheckerDelayed(INACTIVITY_PERIOD_MILLIS, 0L);
         final MockTerminable copyProcess = new MockTerminable();
         final ITimingParameters parameters = new MyTimingParameters(0);
         final CopyActivityMonitor monitor =
-- 
GitLab