From 665248c89a4770e728033b537b453818ce64d7ea Mon Sep 17 00:00:00 2001
From: buczekp <buczekp>
Date: Wed, 23 Mar 2011 17:17:34 +0000
Subject: [PATCH] [LMS-2142] fixed remote implementation of folder comparison,
 improved error handling

SVN: 20477
---
 .../RemoteDataSetFileOperationsExecutor.java  | 43 ++++++++++++++-----
 .../DataSetFileOperationsManager.java         | 19 +++++---
 .../DataSetFileOperationsManagerTest.java     | 16 +++++--
 3 files changed, 57 insertions(+), 21 deletions(-)

diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/RemoteDataSetFileOperationsExecutor.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/RemoteDataSetFileOperationsExecutor.java
index 9cb29b1bc9d..ec99cb74fa7 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/RemoteDataSetFileOperationsExecutor.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/RemoteDataSetFileOperationsExecutor.java
@@ -203,23 +203,15 @@ public final class RemoteDataSetFileOperationsExecutor implements IDataSetFileOp
         ProcessResult result =
                 executor.executeCommandRemotely(cmd, DataSetCopier.SSH_TIMEOUT_MILLIS);
 
-        Map<String, Long> destinationFileSizesByPaths = new LinkedHashMap<String, Long>();
-        if (result.isOK() && result.getOutput() != null)
-        {
-            List<String> output = result.getOutput();
-            for (String line : output)
-            {
-                String split[] = line.split("\t");
-                assert split.length == 2; // silently ignore in production - it will fail later
-                destinationFileSizesByPaths.put(split[0], Long.parseLong(split[1]));
-            }
-        } else
+        if (result.isOK() == false)
         {
             String errorOutput = StringUtilities.concatenateWithNewLine(result.getErrorOutput());
             operationLog.error("Listing files in '" + destination + "' failed with exit value: "
                     + result.getExitValue() + "; error output: " + errorOutput);
             return BooleanStatus.createError("listing files failed");
         }
+        Map<String, Long> destinationFileSizesByPaths =
+                extractDestinationFileSizesByPaths(result.getOutput(), destination);
 
         String inconsistenciesReport =
                 FolderFileSizesReportGenerator.findInconsistencies(dataSetFileSizesByPaths,
@@ -233,6 +225,35 @@ public final class RemoteDataSetFileOperationsExecutor implements IDataSetFileOp
         }
     }
 
+    private Map<String, Long> extractDestinationFileSizesByPaths(List<String> output,
+            File destination)
+    {
+        Map<String, Long> destinationFileSizesByPaths = new LinkedHashMap<String, Long>();
+        for (String line : output)
+        {
+            String split[] = line.split("\t");
+            if (split.length != 2)
+            {
+                throw new ExceptionWithStatus(Status.createError(String.format(
+                        "Unexpected output from find in line: '%s'. "
+                                + "Got %d tokens instead of 2.", line, split.length)));
+            }
+            String filePath = FileUtilities.getRelativeFile(destination, new File(split[0]));
+            String fileSizeAsString = split[1];
+            try
+            {
+                Long fileSize = Long.parseLong(fileSizeAsString);
+                destinationFileSizesByPaths.put(filePath, fileSize);
+            } catch (NumberFormatException ex)
+            {
+                throw new ExceptionWithStatus(Status.createError(String.format(
+                        "Unexpected output from find in line: '%s'. "
+                                + "Expected file size, got '%s'.", line, fileSizeAsString)));
+            }
+        }
+        return destinationFileSizesByPaths;
+    }
+
     /**
      * Returns a bash command listing relative file paths of regular files with their sizes in
      * bytes.
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetFileOperationsManager.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetFileOperationsManager.java
index 95c27396ae3..cd1f7de8f9c 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetFileOperationsManager.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetFileOperationsManager.java
@@ -190,14 +190,21 @@ public class DataSetFileOperationsManager
      */
     public BooleanStatus isPresentInDestination(File originalData, DatasetDescription dataset)
     {
-        File destinationFolder = new File(destination, dataset.getDataSetLocation());
-        BooleanStatus resultStatus = executor.checkSame(originalData, destinationFolder);
-        String message = resultStatus.tryGetMessage(); // if there is a message something went wrong
-        if (message != null)
+        try
         {
-            operationLog.error(message);
+            File destinationFolder = new File(destination, dataset.getDataSetLocation());
+            BooleanStatus resultStatus = executor.checkSame(originalData, destinationFolder);
+            String message = resultStatus.tryGetMessage();
+            if (message != null) // if there is a message something went wrong
+            {
+                operationLog.error(message);
+            }
+            return resultStatus;
+        } catch (ExceptionWithStatus ex)
+        {
+            return BooleanStatus.createError(ex.getStatus().tryGetErrorMessage());
         }
-        return resultStatus;
+
     }
 
     private void checkDestinationExists(File destinationFolder)
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetFileOperationsManagerTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetFileOperationsManagerTest.java
index 74f8c09be40..053ba1a1acc 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetFileOperationsManagerTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetFileOperationsManagerTest.java
@@ -680,8 +680,14 @@ public class DataSetFileOperationsManagerTest extends AbstractFileSystemTestCase
                     one(sshExecutor).executeCommandRemotely(
                             gfindExec.getPath() + " " + ds1ArchivedLocationFile.getPath()
                                     + " -type f -printf \"%p\\t%s\\n\"", SSH_TIMEOUT_MILLIS);
-                    will(returnValue(createOkResultWithOutput(Arrays.asList(
-                            "original/data1_2.txt\t4", "original/fake.txt\t666"))));
+                    String filePath1 =
+                            ds1ArchivedLocationFile.getPath() + File.separator
+                                    + "original/data1_2.txt";
+                    String fakePath =
+                            ds1ArchivedLocationFile.getPath() + File.separator
+                                    + "original/fake.txt";
+                    will(returnValue(createOkResultWithOutput(Arrays.asList(filePath1 + "\t4",
+                            fakePath + "\t666"))));
 
                     /*
                      * ds2: directory is present and content is OK
@@ -691,8 +697,10 @@ public class DataSetFileOperationsManagerTest extends AbstractFileSystemTestCase
                     one(sshExecutor).executeCommandRemotely(
                             gfindExec.getPath() + " " + ds2ArchivedLocationFile.getPath()
                                     + " -type f -printf \"%p\\t%s\\n\"", SSH_TIMEOUT_MILLIS);
-                    will(returnValue(createOkResultWithOutput(Arrays
-                            .asList("original/data2.txt\t12"))));
+                    String filePath2 =
+                            ds2ArchivedLocationFile.getPath() + File.separator
+                                    + "original/data2.txt";
+                    will(returnValue(createOkResultWithOutput(Arrays.asList(filePath2 + "\t12"))));
                 }
             });
         BooleanStatus status1 = dataSetCopier.isPresentInDestination(ds1Location, ds1);
-- 
GitLab