From 3802010e13a0cdc641b116fbfca45cd7ef809328 Mon Sep 17 00:00:00 2001
From: anttil <anttil>
Date: Fri, 30 Aug 2013 08:57:42 +0000
Subject: [PATCH] BIS-506 / SP-841: Zip file based archiver fixes: * Improve
 the message for CRC checksum failures * If the data set is not in the
 path-info-db, just say the data set is not in path-info-db * The script
 should return an error code based on errors found.

SVN: 29693
---
 datastore_server/dist/datastore_server.sh     |  1 +
 .../archiveverifier/batch/BatchResult.java    | 79 +++++++++++++++
 .../DataSetArchiveVerificationResult.java     | 96 +++++++++++++++++++
 .../batch/DataSetArchiveVerifier.java         |  8 +-
 .../archiveverifier/batch/FailedResult.java   | 57 -----------
 .../batch/IArchiveFileVerifier.java           |  2 +-
 .../IDataSetArchiveVerificationBatch.java     |  3 +-
 .../batch/IDataSetArchiveVerifier.java        |  3 +-
 .../dss/archiveverifier/batch/ResultType.java | 17 +++-
 ...erialDataSetArchiveVerificationBatch.java} | 23 +++--
 .../archiveverifier/batch/SkippedResult.java  | 38 --------
 .../archiveverifier/batch/SuccessResult.java  | 49 ----------
 ...ionFailure.java => VerificationError.java} | 26 +++--
 ...Result.java => VerificationErrorType.java} | 11 +--
 ...ataSetArchiveVerificationBatchFactory.java | 17 ++--
 .../openbis/dss/archiveverifier/cli/Main.java |  7 +-
 .../archiveverifier/cli/ResultPrinter.java    | 64 +++++++++----
 .../pathinfo/JdbcPathInfoRepository.java      |  5 +
 .../verifier/AbstractZipFileVerifier.java     | 11 ++-
 .../verifier/CompositeVerifier.java           |  5 +-
 .../verifier/ZipFileHeaderVerifier.java       | 32 ++++---
 .../verifier/ZipFileIntegrityVerifier.java    | 26 +++--
 ...PackagingDataSetFileOperationsManager.java | 17 +---
 .../batch/DataSetArchiveVerifierTest.java     | 16 ++--
 .../ZipFileIntegrityVerifierTest.java         | 11 ++-
 25 files changed, 353 insertions(+), 271 deletions(-)
 create mode 100644 datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/BatchResult.java
 create mode 100644 datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerificationResult.java
 delete mode 100644 datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/FailedResult.java
 rename datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/{DataSetArchiveVerificationBatch.java => SerialDataSetArchiveVerificationBatch.java} (63%)
 delete mode 100644 datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/SkippedResult.java
 delete mode 100644 datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/SuccessResult.java
 rename datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/{ConfigurationFailure.java => VerificationError.java} (64%)
 rename datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/{IResult.java => VerificationErrorType.java} (77%)

diff --git a/datastore_server/dist/datastore_server.sh b/datastore_server/dist/datastore_server.sh
index 6873f90a54c..1960e149266 100755
--- a/datastore_server/dist/datastore_server.sh
+++ b/datastore_server/dist/datastore_server.sh
@@ -283,6 +283,7 @@ case "$command" in
   verify-archives)
     shift
     java -cp "lib/*" ch.systemsx.cisd.openbis.dss.archiveverifier.cli.Main etc/service.properties $*
+    exit $?
     ;;    
   log-thread-dump)
     if [ -f $PIDFILE ]; then
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/BatchResult.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/BatchResult.java
new file mode 100644
index 00000000000..ed52033b86c
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/BatchResult.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2013 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.dss.archiveverifier.batch;
+
+import java.util.Collection;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+/**
+ * Result of a batch verification
+ * 
+ * @author anttil
+ */
+public class BatchResult
+{
+    SortedMap<String, DataSetArchiveVerificationResult> results;
+
+    /**
+     * @param dataSets
+     */
+    public BatchResult(String... dataSets)
+    {
+        this.results = new TreeMap<String, DataSetArchiveVerificationResult>();
+
+        DataSetArchiveVerificationResult missingResult = new DataSetArchiveVerificationResult(VerificationErrorType.ERROR, "dataset not processed");
+
+        for (String dataSet : dataSets)
+        {
+            results.put(dataSet, missingResult);
+        }
+    }
+
+    public int getExitCode()
+    {
+        ResultType max = ResultType.OK;
+        for (DataSetArchiveVerificationResult result : results.values())
+        {
+            if (max.getExitCode() < result.getType().getExitCode())
+            {
+                max = result.getType();
+            }
+        }
+        return max.getExitCode();
+    }
+
+    public void add(String dataSet, DataSetArchiveVerificationResult result)
+    {
+        results.put(dataSet, result);
+    }
+
+    public void add(String dataSet, Exception e)
+    {
+        results.put(dataSet, new DataSetArchiveVerificationResult(e));
+    }
+
+    public Collection<String> getDataSets()
+    {
+        return results.keySet();
+    }
+
+    public DataSetArchiveVerificationResult getResult(String dataSet)
+    {
+        return results.get(dataSet);
+    }
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerificationResult.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerificationResult.java
new file mode 100644
index 00000000000..9245f89441c
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerificationResult.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2013 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.dss.archiveverifier.batch;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Result of verification of a data set archive
+ * 
+ * @author anttil
+ */
+public class DataSetArchiveVerificationResult
+{
+
+    private File file;
+
+    private List<VerificationError> errors;
+
+    public DataSetArchiveVerificationResult(File file, List<VerificationError> errors)
+    {
+        this.file = file;
+        this.errors = errors;
+    }
+
+    public DataSetArchiveVerificationResult(VerificationErrorType type, String message)
+    {
+        this.file = null;
+        this.errors = Collections.singletonList(new VerificationError(type, message));
+    }
+
+    public DataSetArchiveVerificationResult(Exception e)
+    {
+        this.file = null;
+        this.errors = Collections.singletonList(new VerificationError(VerificationErrorType.ERROR, e.getClass().getName()+":"+e.getMessage()));
+    }
+
+    public ResultType getType()
+    {
+        if (errors.isEmpty())
+        {
+            return ResultType.OK;
+
+        }
+        // find the maximum error
+        VerificationErrorType errorType = VerificationErrorType.WARNING;
+        for (VerificationError error : errors)
+        {
+            errorType = errorType.compareTo(error.getType()) > 0 ? errorType : error.getType();
+        }
+
+        switch (errorType)
+        {
+            case WARNING:
+                return ResultType.WARNING;
+            case ERROR:
+                return ResultType.ERROR;
+            case FATAL:
+                return ResultType.FATAL;
+            default:
+                throw new IllegalStateException("unknown error type " + errorType);
+        }
+    }
+
+    public List<VerificationError> getErrors()
+    {
+        return errors;
+    }
+
+    public String getFileName()
+    {
+        if (file != null)
+        {
+            return file.getAbsolutePath();
+        } else
+        {
+            return "file not found";
+        }
+    }
+
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerifier.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerifier.java
index dad66e8b0a0..46ce75a5f14 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerifier.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerifier.java
@@ -37,16 +37,16 @@ public class DataSetArchiveVerifier implements IDataSetArchiveVerifier
     }
 
     @Override
-    public IResult run(String dataSetCode)
+    public DataSetArchiveVerificationResult run(String dataSetCode)
     {
         File file = fileRepository.getArchiveFileOf(dataSetCode);
         if (file.exists())
         {
-            List<String> errors = verifier.verify(file);
-            return errors.isEmpty() ? new SuccessResult(file) : new FailedResult(file, errors);
+            List<VerificationError> errors = verifier.verify(file);
+            return new DataSetArchiveVerificationResult(file, errors);
         } else
         {
-            return new SkippedResult();
+            return new DataSetArchiveVerificationResult(VerificationErrorType.ERROR, "file not found");
         }
     }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/FailedResult.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/FailedResult.java
deleted file mode 100644
index 00914c2496e..00000000000
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/FailedResult.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2013 ETH Zuerich, CISD
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package ch.systemsx.cisd.openbis.dss.archiveverifier.batch;
-
-import java.io.File;
-import java.io.PrintStream;
-import java.util.List;
-
-/**
- * Result of verification with errors.
- * 
- * @author anttil
- */
-public class FailedResult implements IResult
-{
-
-    private final File file;
-
-    private final List<String> errors;
-
-    public FailedResult(File file, List<String> errors)
-    {
-        this.file = file;
-        this.errors = errors;
-    }
-
-    @Override
-    public void printTo(String dataSet, PrintStream out)
-    {
-        out.println("FAILED - " + dataSet + " (" + file + ")");
-        for (String error : errors)
-        {
-            out.println("  " + error);
-        }
-    }
-
-    @Override
-    public ResultType getType()
-    {
-        return ResultType.FAILED;
-    }
-
-}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IArchiveFileVerifier.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IArchiveFileVerifier.java
index ff84fcc37da..f4579e98a54 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IArchiveFileVerifier.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IArchiveFileVerifier.java
@@ -29,5 +29,5 @@ public interface IArchiveFileVerifier
     /**
      * Returns a list of errors. If verification is successful, the list is empty.
      */
-    public List<String> verify(File file);
+    public List<VerificationError> verify(File file);
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IDataSetArchiveVerificationBatch.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IDataSetArchiveVerificationBatch.java
index 4b07cff0761..4c519801e2e 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IDataSetArchiveVerificationBatch.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IDataSetArchiveVerificationBatch.java
@@ -16,7 +16,6 @@
 
 package ch.systemsx.cisd.openbis.dss.archiveverifier.batch;
 
-import java.util.SortedMap;
 
 /**
  * A batch verification of dataset archive files
@@ -25,5 +24,5 @@ import java.util.SortedMap;
  */
 public interface IDataSetArchiveVerificationBatch
 {
-    SortedMap<String, IResult> run();
+    BatchResult run();
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IDataSetArchiveVerifier.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IDataSetArchiveVerifier.java
index 84e584a95c0..441dd6c15ae 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IDataSetArchiveVerifier.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IDataSetArchiveVerifier.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.openbis.dss.archiveverifier.batch;
 
+
 /**
  * An archive file verification for a dataset.
  * 
@@ -23,5 +24,5 @@ package ch.systemsx.cisd.openbis.dss.archiveverifier.batch;
  */
 public interface IDataSetArchiveVerifier
 {
-    IResult run(String dataSetCode);
+    DataSetArchiveVerificationResult run(String dataSetCode);
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/ResultType.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/ResultType.java
index 02e4b3a1d5d..b3750a9f598 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/ResultType.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/ResultType.java
@@ -17,11 +17,24 @@
 package ch.systemsx.cisd.openbis.dss.archiveverifier.batch;
 
 /**
- * Type of a verification result.
+ * Type of a result of verifiying a single data set archive.
  * 
  * @author anttil
  */
 public enum ResultType
 {
-    OK, FAILED, SKIPPED, FATAL;
+    OK(0), WARNING(1), ERROR(2), FATAL(2);
+
+    private final int exitCode;
+
+    private ResultType(int exitCode)
+    {
+        this.exitCode = exitCode;
+    }
+
+    public int getExitCode()
+    {
+        return this.exitCode;
+    }
+
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerificationBatch.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/SerialDataSetArchiveVerificationBatch.java
similarity index 63%
rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerificationBatch.java
rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/SerialDataSetArchiveVerificationBatch.java
index aa0363dc724..4b38b9f0366 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerificationBatch.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/SerialDataSetArchiveVerificationBatch.java
@@ -16,37 +16,42 @@
 
 package ch.systemsx.cisd.openbis.dss.archiveverifier.batch;
 
-import java.util.SortedMap;
-import java.util.TreeMap;
 
 /**
  * Runs archive verification for a list of datasets.
  * 
  * @author anttil
  */
-public class DataSetArchiveVerificationBatch implements IDataSetArchiveVerificationBatch
+public class SerialDataSetArchiveVerificationBatch implements IDataSetArchiveVerificationBatch
 {
 
     private final IDataSetArchiveVerifier verifier;
 
     private final String[] dataSets;
 
-    public DataSetArchiveVerificationBatch(IDataSetArchiveVerifier verifier, String... dataSets)
+    public SerialDataSetArchiveVerificationBatch(IDataSetArchiveVerifier verifier, String... dataSets)
     {
         this.verifier = verifier;
         this.dataSets = dataSets;
     }
 
     @Override
-    public SortedMap<String, IResult> run()
+    public BatchResult run()
     {
-        SortedMap<String, IResult> results = new TreeMap<String, IResult>();
+        BatchResult batchResult = new BatchResult(dataSets);
 
         for (String dataSet : dataSets)
         {
-            IResult result = verifier.run(dataSet);
-            results.put(dataSet, result);
+            DataSetArchiveVerificationResult result = verifier.run(dataSet);
+
+            try
+            {
+                batchResult.add(dataSet, result);
+            } catch (Exception e)
+            {
+                batchResult.add(dataSet, e);
+            }
         }
-        return results;
+        return batchResult;
     }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/SkippedResult.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/SkippedResult.java
deleted file mode 100644
index e0500115c43..00000000000
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/SkippedResult.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2013 ETH Zuerich, CISD
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package ch.systemsx.cisd.openbis.dss.archiveverifier.batch;
-
-import java.io.PrintStream;
-
-/**
- * @author anttil
- */
-public class SkippedResult implements IResult
-{
-
-    @Override
-    public void printTo(String dataSet, PrintStream out)
-    {
-        out.println("NOT TESTED - " + dataSet + " (file not found)");
-    }
-
-    @Override
-    public ResultType getType()
-    {
-        return ResultType.SKIPPED;
-    }
-}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/SuccessResult.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/SuccessResult.java
deleted file mode 100644
index 7b5c75c7354..00000000000
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/SuccessResult.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2013 ETH Zuerich, CISD
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package ch.systemsx.cisd.openbis.dss.archiveverifier.batch;
-
-import java.io.File;
-import java.io.PrintStream;
-
-/**
- * Result of successfull verification
- * 
- * @author anttil
- */
-public class SuccessResult implements IResult
-{
-
-    private final File file;
-
-    public SuccessResult(File file)
-    {
-        this.file = file;
-    }
-
-    @Override
-    public void printTo(String dataSet, PrintStream out)
-    {
-        out.println("OK - " + dataSet + " (" + file + ")");
-    }
-
-    @Override
-    public ResultType getType()
-    {
-        return ResultType.OK;
-    }
-
-}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/ConfigurationFailure.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/VerificationError.java
similarity index 64%
rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/ConfigurationFailure.java
rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/VerificationError.java
index 526b51c312d..42d103179e6 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/ConfigurationFailure.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/VerificationError.java
@@ -16,32 +16,30 @@
 
 package ch.systemsx.cisd.openbis.dss.archiveverifier.batch;
 
-import java.io.PrintStream;
-
 /**
- * Result of configuration failure.
+ * Describes a single error in verifying an archive file.
  * 
  * @author anttil
  */
-public class ConfigurationFailure implements IResult
+public class VerificationError
 {
-    private final String error;
+    private VerificationErrorType type;
+
+    private String message;
 
-    public ConfigurationFailure(String error)
+    public VerificationError(VerificationErrorType type, String message)
     {
-        this.error = error;
+        this.type = type;
+        this.message = message;
     }
 
-    @Override
-    public void printTo(String dataSet, PrintStream out)
+    public VerificationErrorType getType()
     {
-        out.println(error);
+        return type;
     }
 
-    @Override
-    public ResultType getType()
+    public String getMessage()
     {
-        return ResultType.FATAL;
+        return this.message;
     }
-
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IResult.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/VerificationErrorType.java
similarity index 77%
rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IResult.java
rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/VerificationErrorType.java
index be613d0487c..764fb4ee1a7 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/IResult.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/VerificationErrorType.java
@@ -16,16 +16,13 @@
 
 package ch.systemsx.cisd.openbis.dss.archiveverifier.batch;
 
-import java.io.PrintStream;
-
 /**
- * Result of verification of a dataset archive file.
+ * Severity of a verification error.
  * 
  * @author anttil
  */
-public interface IResult
+public enum VerificationErrorType
 {
-    public void printTo(String dataSet, PrintStream out);
-
-    public ResultType getType();
+    // don't change the order as the code depends on it
+    WARNING, ERROR, FATAL;
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/cli/DataSetArchiveVerificationBatchFactory.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/cli/DataSetArchiveVerificationBatchFactory.java
index 926840933b4..3d71ae15222 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/cli/DataSetArchiveVerificationBatchFactory.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/cli/DataSetArchiveVerificationBatchFactory.java
@@ -28,16 +28,15 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Properties;
-import java.util.SortedMap;
-import java.util.TreeMap;
 
-import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.ConfigurationFailure;
-import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.DataSetArchiveVerificationBatch;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.BatchResult;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.DataSetArchiveVerificationResult;
 import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.DataSetArchiveVerifier;
 import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.IArchiveFileRepository;
 import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.IArchiveFileVerifier;
 import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.IDataSetArchiveVerificationBatch;
-import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.IResult;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.SerialDataSetArchiveVerificationBatch;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.VerificationErrorType;
 import ch.systemsx.cisd.openbis.dss.archiveverifier.filesystem.FileSystemArchiveFileRepository;
 import ch.systemsx.cisd.openbis.dss.archiveverifier.filesystem.FlatFileLocator;
 import ch.systemsx.cisd.openbis.dss.archiveverifier.filesystem.IFileLocator;
@@ -84,7 +83,7 @@ public class DataSetArchiveVerificationBatchFactory
             List<IArchiveFileVerifier> verifiers = getVerifiers(properties, pathInfoRepository);
             DataSetArchiveVerifier verifier = new DataSetArchiveVerifier(archiveFileRepository, new CompositeVerifier(verifiers));
 
-            return new DataSetArchiveVerificationBatch(verifier, Arrays.copyOfRange(args, 1, args.length));
+            return new SerialDataSetArchiveVerificationBatch(verifier, Arrays.copyOfRange(args, 1, args.length));
 
         } catch (ConfigurationException e)
         {
@@ -92,10 +91,10 @@ public class DataSetArchiveVerificationBatchFactory
             return new IDataSetArchiveVerificationBatch()
                 {
                     @Override
-                    public SortedMap<String, IResult> run()
+                    public BatchResult run()
                     {
-                        SortedMap<String, IResult> result = new TreeMap<String, IResult>();
-                        result.put("Failed to start", new ConfigurationFailure(error));
+                        BatchResult result = new BatchResult();
+                        result.add("", new DataSetArchiveVerificationResult(VerificationErrorType.FATAL, error));
                         return result;
                     }
                 };
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/cli/Main.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/cli/Main.java
index 7bd30b813b2..f050e9e7dca 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/cli/Main.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/cli/Main.java
@@ -16,10 +16,8 @@
 
 package ch.systemsx.cisd.openbis.dss.archiveverifier.cli;
 
-import java.util.Map;
-
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.BatchResult;
 import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.IDataSetArchiveVerificationBatch;
-import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.IResult;
 
 /**
  * Run a batch of dataset archive file verifications. First command line argument: path to service.properties of local DSS. Rest of the arguments:
@@ -32,7 +30,8 @@ public class Main
     public static void main(String[] args)
     {
         IDataSetArchiveVerificationBatch batch = new DataSetArchiveVerificationBatchFactory(args).build();
-        Map<String, IResult> result = batch.run();
+        BatchResult result = batch.run();
         new ResultPrinter(System.out).print(result);
+        System.exit(result.getExitCode());
     }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/cli/ResultPrinter.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/cli/ResultPrinter.java
index 32edc474010..9c5131f0dcd 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/cli/ResultPrinter.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/cli/ResultPrinter.java
@@ -17,11 +17,15 @@
 package ch.systemsx.cisd.openbis.dss.archiveverifier.cli;
 
 import java.io.PrintStream;
+import java.util.Collection;
 import java.util.EnumMap;
 import java.util.Map;
 
-import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.IResult;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.BatchResult;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.DataSetArchiveVerificationResult;
 import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.ResultType;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.VerificationError;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.VerificationErrorType;
 
 /**
  * Prints the results of a dataset archive batch verification.
@@ -38,21 +42,46 @@ public class ResultPrinter
         this.out = out;
     }
 
-    public void print(Map<String, IResult> results)
+    public void print(BatchResult result)
     {
         Map<ResultType, Integer> counts = createCountMap();
 
-        for (String dataSet : results.keySet())
+        for (String dataSet : result.getDataSets())
         {
-            IResult result = results.get(dataSet);
-            result.printTo(dataSet, out);
-            ResultType type = result.getType();
+            DataSetArchiveVerificationResult dataSetResult = result.getResult(dataSet);
+            printResult(dataSet, dataSetResult);
+
+            ResultType type = dataSetResult.getType();
             counts.put(type, counts.get(type) + 1);
         }
 
         printTotals(counts);
     }
 
+    private void printResult(String dataSet, DataSetArchiveVerificationResult result)
+    {
+        Collection<VerificationError> errors = result.getErrors();
+
+        if (errors.isEmpty())
+        {
+            out.println("OK: " + dataSet + " (" + result.getFileName() + ")");
+            return;
+        }
+
+        for (VerificationError error : errors)
+        {
+            VerificationErrorType type = error.getType();
+            if (VerificationErrorType.FATAL.equals(type))
+            {
+                out.println(result.getErrors().get(0).getMessage());
+            } else
+            {
+                out.println(type + " in " + dataSet + " (" + result.getFileName() + "): " + error.getMessage());
+            }
+
+        }
+    }
+
     private Map<ResultType, Integer> createCountMap()
     {
         Map<ResultType, Integer> counts = new EnumMap<ResultType, Integer>(ResultType.class);
@@ -66,10 +95,11 @@ public class ResultPrinter
     private void printTotals(Map<ResultType, Integer> counts)
     {
         int ok = counts.get(ResultType.OK);
-        int failed = counts.get(ResultType.FAILED);
-        int notTested = counts.get(ResultType.SKIPPED);
+        int warning = counts.get(ResultType.WARNING);
+        int error = counts.get(ResultType.ERROR);
         int fatal = counts.get(ResultType.FATAL);
-        int total = ok + failed;
+
+        int total = ok + warning + error;
 
         if (fatal > 0)
         {
@@ -80,17 +110,19 @@ public class ResultPrinter
         out.println("---");
         out.println("Total of " + total + " dataset archives tested.");
 
-        if (failed == 0)
+        if (warning + error == 0)
         {
             out.println("No errors found");
         } else
         {
-            out.println("Errors found in " + failed + " archive file(s).");
-        }
-
-        if (notTested > 0)
-        {
-            out.println("Could not find archive file for " + notTested + " dataset(s).");
+            if (error > 0)
+            {
+                out.println(error + " archive file(s) contained errors.");
+            }
+            if (warning > 0)
+            {
+                out.println(warning + " archive file(s) caused warnings");
+            }
         }
     }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/pathinfo/JdbcPathInfoRepository.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/pathinfo/JdbcPathInfoRepository.java
index f6f85d31e4a..5f442dd8753 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/pathinfo/JdbcPathInfoRepository.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/pathinfo/JdbcPathInfoRepository.java
@@ -56,6 +56,11 @@ public class JdbcPathInfoRepository implements IArchiveFileMetaDataRepository
 
             final Map<String, PathInfoEntry> data = new HashMap<String, PathInfoEntry>();
 
+            if (result.isBeforeFirst() == false)
+            {
+                return null;
+            }
+
             while (result.next())
             {
                 final String file = result.getString("relative_path");
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/AbstractZipFileVerifier.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/AbstractZipFileVerifier.java
index 7c282b7e6e9..842e7b3e0bf 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/AbstractZipFileVerifier.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/AbstractZipFileVerifier.java
@@ -25,7 +25,8 @@ import java.util.List;
 import java.util.zip.CRC32;
 
 import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.IArchiveFileVerifier;
-
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.VerificationError;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.VerificationErrorType;
 
 import de.schlichtherle.util.zip.ZipFile;
 
@@ -37,19 +38,19 @@ import de.schlichtherle.util.zip.ZipFile;
 public abstract class AbstractZipFileVerifier implements IArchiveFileVerifier
 {
 
-    public abstract List<String> verify(ZipFile file);
+    public abstract List<VerificationError> verify(ZipFile file);
 
     @Override
-    public final List<String> verify(File file)
+    public final List<VerificationError> verify(File file)
     {
-        List<String> errors = new ArrayList<String>();
+        List<VerificationError> errors = new ArrayList<VerificationError>();
         ZipFile zip;
         try
         {
             zip = new ZipFile(file);
         } catch (IOException ex)
         {
-            errors.add("Reading zip file failed: " + ex.getMessage());
+            errors.add(new VerificationError(VerificationErrorType.ERROR, "Reading zip file failed: " + ex.getMessage()));
             return errors;
         }
 
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/CompositeVerifier.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/CompositeVerifier.java
index bc31ca15811..15284977973 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/CompositeVerifier.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/CompositeVerifier.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.IArchiveFileVerifier;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.VerificationError;
 
 /**
  * Combines multiple verifiers to one.
@@ -38,9 +39,9 @@ public class CompositeVerifier implements IArchiveFileVerifier
     }
 
     @Override
-    public List<String> verify(File file)
+    public List<VerificationError> verify(File file)
     {
-        List<String> errors = new ArrayList<String>();
+        List<VerificationError> errors = new ArrayList<VerificationError>();
         for (IArchiveFileVerifier verifier : verifiers)
         {
             errors.addAll(verifier.verify(file));
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/ZipFileHeaderVerifier.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/ZipFileHeaderVerifier.java
index 5e80b08c3d5..5dd36480565 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/ZipFileHeaderVerifier.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/ZipFileHeaderVerifier.java
@@ -22,6 +22,8 @@ import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
 
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.VerificationError;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.VerificationErrorType;
 import ch.systemsx.cisd.openbis.dss.generic.server.AbstractDataSetPackager;
 
 import de.schlichtherle.util.zip.ZipEntry;
@@ -46,9 +48,9 @@ public class ZipFileHeaderVerifier extends AbstractZipFileVerifier
     }
 
     @Override
-    public List<String> verify(ZipFile zip)
+    public List<VerificationError> verify(ZipFile zip)
     {
-        List<String> errors = new ArrayList<String>();
+        List<VerificationError> result = new ArrayList<VerificationError>();
 
         String filename = zip.getName();
         String dataSetCode = filename.substring(filename.lastIndexOf("/") + 1, filename.lastIndexOf("."));
@@ -57,8 +59,8 @@ public class ZipFileHeaderVerifier extends AbstractZipFileVerifier
         IArchiveFileContent metaData = fileMetaDataRepository.getMetaData(dataSetCode);
         if (metaData == null)
         {
-            errors.add("Could not find entry for dataset in " + repositoryName);
-            return errors;
+            result.add(new VerificationError(VerificationErrorType.WARNING, "Could not find entry for dataset in " + repositoryName));
+            return result;
         }
 
         Enumeration<?> entries = zip.entries();
@@ -75,14 +77,15 @@ public class ZipFileHeaderVerifier extends AbstractZipFileVerifier
             Long externalSize = metaData.getFileSize(entryName);
             if (externalSize == null)
             {
-                errors.add("Could not find entry for file " + entryName + " in " + repositoryName);
+                result.add(new VerificationError(VerificationErrorType.ERROR, "Could not find entry for file " + entryName + " in " + repositoryName));
                 continue;
             }
 
             if (entry.getSize() != externalSize)
             {
-                errors.add(entryName + ": size in archive file: " + entry.getSize() + ", size in " + repositoryName + ": "
-                        + externalSize);
+                result.add(new VerificationError(VerificationErrorType.ERROR, entryName + ": size in archive file: " + entry.getSize() + ", size in "
+                        + repositoryName + ": "
+                        + externalSize));
             }
 
             Long externalCrc = metaData.getFileCrc(entryName);
@@ -90,19 +93,22 @@ public class ZipFileHeaderVerifier extends AbstractZipFileVerifier
             {
                 if (externalCrc == null)
                 {
-                    errors.add(entryName + ": no CRC32 found in " + repositoryName);
+                    result.add(new VerificationError(VerificationErrorType.ERROR, entryName + ": no CRC32 found in " + repositoryName));
 
                 } else if (externalCrc != entry.getCrc())
                 {
-                    errors.add(entryName + ": CRC32 in archive file: " + crc32ToString((int) entry.getCrc()) + ", CRC32 in " + repositoryName + ": "
-                            + crc32ToString((int) externalCrc.longValue()));
+                    result.add(new VerificationError(VerificationErrorType.ERROR, entryName + ": CRC32 in archive file: "
+                            + crc32ToString((int) entry.getCrc()) + ", CRC32 in "
+                            + repositoryName + ": "
+                            + crc32ToString((int) externalCrc.longValue())));
                 }
             } else if (externalCrc != null)
             {
-                errors.add(entryName + ": CRC32 found in " + repositoryName + " even it should be disabled. Value was "
-                        + crc32ToString((int) externalCrc.longValue()));
+                result.add(new VerificationError(VerificationErrorType.ERROR, entryName + ": CRC32 found in " + repositoryName
+                        + " even it should be disabled. Value was "
+                        + crc32ToString((int) externalCrc.longValue())));
             }
         }
-        return errors;
+        return result;
     }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/ZipFileIntegrityVerifier.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/ZipFileIntegrityVerifier.java
index 66f94f1644d..759f6c2f815 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/ZipFileIntegrityVerifier.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/ZipFileIntegrityVerifier.java
@@ -21,12 +21,13 @@ import static ch.systemsx.cisd.common.io.IOUtilities.crc32ToString;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.Enumeration;
 import java.util.List;
 import java.util.zip.ZipException;
 
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.VerificationError;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.VerificationErrorType;
+
 import de.schlichtherle.util.zip.ZipEntry;
 import de.schlichtherle.util.zip.ZipFile;
 
@@ -39,20 +40,24 @@ public class ZipFileIntegrityVerifier extends AbstractZipFileVerifier
 {
 
     @Override
-    public List<String> verify(ZipFile zip)
+    public List<VerificationError> verify(ZipFile zip)
     {
-        List<String> errors = new ArrayList<String>();
+        List<VerificationError> errors = new ArrayList<VerificationError>();
 
         Enumeration<?> entries = zip.entries();
         while (entries.hasMoreElements())
         {
             ZipEntry entry = (ZipEntry) entries.nextElement();
-            errors.addAll(checkZipEntry(zip, entry));
+            VerificationError error = checkZipEntry(zip, entry);
+            if (error != null)
+            {
+                errors.add(error);
+            }
         }
         return errors;
     }
 
-    private Collection<String> checkZipEntry(ZipFile zip, ZipEntry entry)
+    private VerificationError checkZipEntry(ZipFile zip, ZipEntry entry)
     {
         InputStream input = null;
         try
@@ -61,16 +66,17 @@ public class ZipFileIntegrityVerifier extends AbstractZipFileVerifier
             long crc = calculateCRC32(input);
             if (crc != entry.getCrc())
             {
-                return Arrays.asList(entry.getName() + ": CRC failure (got " + crc32ToString((int) crc) + ", should be "
+                return new VerificationError(VerificationErrorType.ERROR, entry.getName() + ": CRC failure (calculated: " + crc32ToString((int) crc)
+                        + ", zip file header: "
                         + crc32ToString((int) entry.getCrc()) + ")");
             }
 
         } catch (ZipException ex)
         {
-            return Arrays.asList(ex.getMessage());
+            return new VerificationError(VerificationErrorType.ERROR, ex.getMessage());
         } catch (IOException ex)
         {
-            return Arrays.asList(entry.getName() + ": " + ex.getMessage());
+            return new VerificationError(VerificationErrorType.ERROR, entry.getName() + ": " + ex.getMessage());
         } finally
         {
             if (input != null)
@@ -83,6 +89,6 @@ public class ZipFileIntegrityVerifier extends AbstractZipFileVerifier
                 }
             }
         }
-        return new ArrayList<String>();
+        return null;
     }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DistributedPackagingDataSetFileOperationsManager.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DistributedPackagingDataSetFileOperationsManager.java
index 22b1752ff53..105e559c154 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DistributedPackagingDataSetFileOperationsManager.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DistributedPackagingDataSetFileOperationsManager.java
@@ -22,10 +22,8 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Enumeration;
-import java.util.List;
 import java.util.Properties;
 
 import org.apache.commons.io.IOUtils;
@@ -45,7 +43,7 @@ import ch.systemsx.cisd.openbis.common.io.hierarchical_content.IHierarchicalCont
 import ch.systemsx.cisd.openbis.common.io.hierarchical_content.ZipBasedHierarchicalContent;
 import ch.systemsx.cisd.openbis.common.io.hierarchical_content.api.IHierarchicalContent;
 import ch.systemsx.cisd.openbis.common.io.hierarchical_content.api.IHierarchicalContentNode;
-import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.IArchiveFileVerifier;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.VerificationError;
 import ch.systemsx.cisd.openbis.dss.archiveverifier.verifier.ZipFileIntegrityVerifier;
 import ch.systemsx.cisd.openbis.dss.generic.server.AbstractDataSetPackager;
 import ch.systemsx.cisd.openbis.dss.generic.server.ZipDataSetPackager;
@@ -171,8 +169,7 @@ public class DistributedPackagingDataSetFileOperationsManager implements IDataSe
 
                     if (Status.OK.equals(status))
                     {
-                        List<String> errors =
-                                verify(file, new ZipFileIntegrityVerifier());
+                        Collection<VerificationError> errors = new ZipFileIntegrityVerifier().verify(file);
 
                         if (errors.size() > 0)
                         {
@@ -192,16 +189,6 @@ public class DistributedPackagingDataSetFileOperationsManager implements IDataSe
         return status;
     }
 
-    private List<String> verify(File file, IArchiveFileVerifier... verifiers)
-    {
-        List<String> errors = new ArrayList<String>();
-        for (IArchiveFileVerifier verifier : verifiers)
-        {
-            errors.addAll(verifier.verify(file));
-        }
-        return errors;
-    }
-
     private AbstractDataSetPackager createPackager(File file, DataSetExistenceChecker dataSetExistenceChecker)
     {
         return new ZipDataSetPackager(file, compress, getContentProvider(), dataSetExistenceChecker);
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerifierTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerifierTest.java
index 2432d818c5d..b3207d0929c 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerifierTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/archiveverifier/batch/DataSetArchiveVerifierTest.java
@@ -21,7 +21,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
 
 import java.io.File;
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 
 import org.jmock.Expectations;
 import org.jmock.Mockery;
@@ -33,22 +33,22 @@ public class DataSetArchiveVerifierTest
     @Test
     public void successfulVerificationCausesSuccessResult() throws Exception
     {
-        IResult result = verifier.run(CODE_OF_DATASET_WITH_GOOD_ARCHIVE);
+        DataSetArchiveVerificationResult result = verifier.run(CODE_OF_DATASET_WITH_GOOD_ARCHIVE);
         assertThat(result.getType(), is(ResultType.OK));
     }
 
     @Test
     public void failingVerificationCausesFailedResult() throws Exception
     {
-        IResult result = verifier.run(CODE_OF_DATASET_WITH_BAD_ARCHIVE);
-        assertThat(result.getType(), is(ResultType.FAILED));
+        DataSetArchiveVerificationResult result = verifier.run(CODE_OF_DATASET_WITH_BAD_ARCHIVE);
+        assertThat(result.getType(), is(ResultType.ERROR));
     }
 
     @Test
     public void failureToLocateArchiveFileCausesFailedResult() throws Exception
     {
-        IResult result = verifier.run(CODE_OF_DATASET_WITHOUT_AN_ARCHIVE_FILE);
-        assertThat(result.getType(), is(ResultType.SKIPPED));
+        DataSetArchiveVerificationResult result = verifier.run(CODE_OF_DATASET_WITHOUT_AN_ARCHIVE_FILE);
+        assertThat(result.getType(), is(ResultType.ERROR));
     }
 
     @BeforeMethod
@@ -66,13 +66,13 @@ public class DataSetArchiveVerifierTest
                     will(returnValue(GOOD_ARCHIVE_FILE));
 
                     allowing(fileVerifier).verify(GOOD_ARCHIVE_FILE);
-                    will(returnValue(new ArrayList<String>()));
+                    will(returnValue(new ArrayList<VerificationError>()));
 
                     allowing(fileRepository).getArchiveFileOf(CODE_OF_DATASET_WITH_BAD_ARCHIVE);
                     will(returnValue(BAD_ARCHIVE_FILE));
 
                     allowing(fileVerifier).verify(BAD_ARCHIVE_FILE);
-                    will(returnValue(Arrays.asList("error1, error2")));
+                    will(returnValue(Collections.singletonList(new VerificationError(VerificationErrorType.ERROR, "error"))));
 
                     allowing(fileRepository).getArchiveFileOf(CODE_OF_DATASET_WITHOUT_AN_ARCHIVE_FILE);
                     will(returnValue(NONEXISTING_FILE));
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/ZipFileIntegrityVerifierTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/ZipFileIntegrityVerifierTest.java
index 8b648190ad3..132d9a15624 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/ZipFileIntegrityVerifierTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/archiveverifier/verifier/ZipFileIntegrityVerifierTest.java
@@ -20,40 +20,41 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import java.io.File;
-import java.util.List;
+import java.util.Collection;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.IArchiveFileVerifier;
+import ch.systemsx.cisd.openbis.dss.archiveverifier.batch.VerificationError;
 
 public class ZipFileIntegrityVerifierTest
 {
     @Test
     public void verificationOfZipFileWithCRCErrorFails() throws Exception
     {
-        List<String> errors = verifier.verify(FILE_WITH_CRC_ERROR);
+        Collection<VerificationError> errors = verifier.verify(FILE_WITH_CRC_ERROR);
         assertThat(errors.isEmpty(), is(false));
     }
 
     @Test
     public void verificationOfInvalidZipFileFails() throws Exception
     {
-        List<String> errors = verifier.verify(INVALID_ZIP_FILE);
+        Collection<VerificationError> errors = verifier.verify(INVALID_ZIP_FILE);
         assertThat(errors.isEmpty(), is(false));
     }
 
     @Test
     public void verificationOfNonExistingFileFails() throws Exception
     {
-        List<String> errors = verifier.verify(NONEXISTING_FILE);
+        Collection<VerificationError> errors = verifier.verify(NONEXISTING_FILE);
         assertThat(errors.isEmpty(), is(false));
     }
 
     @Test
     public void verificationOfValidZipFileSucceeds() throws Exception
     {
-        List<String> errors = verifier.verify(VALID_ZIP_FILE);
+        Collection<VerificationError> errors = verifier.verify(VALID_ZIP_FILE);
         assertThat(errors.isEmpty(), is(true));
     }
 
-- 
GitLab