From 1df198b4aed20f91427da92bf4bbff33a0b1b7dc Mon Sep 17 00:00:00 2001
From: Andreas Romeyke <andreas.romeyke@slub-dresden.de>
Date: Wed, 25 Jan 2023 20:03:59 +0100
Subject: [PATCH] - added null-checks in parameter getters - fixed
 throughput(), return result - added contractAssert...() - increased debugging
 output - fixed wrong retrieveEntity() call, uses relative paths - added
 relativePath() -

---
 PLUGIN-INF/metadata_SLUBStoragePlugin.xml     |   2 +-
 .../plugin/storage/nfs/SLUBStoragePlugin.java | 150 ++++++++++++------
 .../storage/nfs/TestSLUBStoragePlugin.java    |  23 ++-
 3 files changed, 126 insertions(+), 49 deletions(-)

diff --git a/PLUGIN-INF/metadata_SLUBStoragePlugin.xml b/PLUGIN-INF/metadata_SLUBStoragePlugin.xml
index 3a64c2f..8041203 100644
--- a/PLUGIN-INF/metadata_SLUBStoragePlugin.xml
+++ b/PLUGIN-INF/metadata_SLUBStoragePlugin.xml
@@ -70,7 +70,7 @@
 		</fr:x_form>
 	</pl:initParameters>
 	<pl:description>SLUB Storage Plugin</pl:description>
-	<pl:version>2.822</pl:version>
+	<pl:version>2.836</pl:version>
 	<pl:materialType>DIGITAL</pl:materialType>
 	<pl:module>Repository</pl:module>
 	<pl:generalType>TASK</pl:generalType>
diff --git a/java/org/slub/rosetta/dps/repository/plugin/storage/nfs/SLUBStoragePlugin.java b/java/org/slub/rosetta/dps/repository/plugin/storage/nfs/SLUBStoragePlugin.java
index 7342635..7330229 100644
--- a/java/org/slub/rosetta/dps/repository/plugin/storage/nfs/SLUBStoragePlugin.java
+++ b/java/org/slub/rosetta/dps/repository/plugin/storage/nfs/SLUBStoragePlugin.java
@@ -25,7 +25,6 @@ import com.exlibris.core.infra.common.util.IOUtil;
 import com.exlibris.core.infra.svc.api.scriptRunner.ExecExternalProcess;
 import com.exlibris.core.sdk.storage.containers.StoredEntityMetaData;
 import com.exlibris.core.sdk.storage.handler.AbstractStorageHandler;
-import com.exlibris.core.sdk.storage.handler.StorageHandler;
 import com.exlibris.core.sdk.storage.handler.StorageUtil;
 import com.exlibris.core.sdk.utils.FileUtil;
 import com.exlibris.digitool.common.dnx.DnxDocument;
@@ -76,27 +75,40 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
     private static final ExLogger log = ExLogger.getExLogger(SLUBStoragePlugin.class);
 
     private String getDirRoot () {
-        return parameters.get("DIR_ROOT");
+        String path = parameters.get("DIR_ROOT");
+        if (null == path) {
+            log.error("Could not retrieve DIR_ROOT");
+        }
+        return path;
     }
     private int getBlockSize () {
         int blockSize = 32*1024;
+        String blocksizeStr = this.parameters.get("BLOCK_SIZE");
+        if (null == blocksizeStr) {
+            log.error("Could not retrieve BLOCK_SIZE");
+        }
         try {
-            blockSize = Integer.parseInt(this.parameters.get("BLOCK_SIZE"));
+            blockSize = Integer.parseInt(blocksizeStr);
         } catch (NumberFormatException e) {
-            log.error("Could not convert BLOCK_SIZE string to int, " + e);
+            log.error("Could not convert BLOCK_SIZE string to int, " + e.getMessage());
             blockSize = 32*1024;
         }
         return blockSize;
     }
     private String getFilesHandlingMethod () {
-        return this.parameters.get("FILES_HANDLING_METHOD");
+        String filehandlingMethod = this.parameters.get("FILES_HANDLING_METHOD");
+        if (null == filehandlingMethod) {
+            log.error("Could not retrieve FILES_HANDLING_METHOD");
+        }
+        return filehandlingMethod;
     }
 
     private String throughput(long starttime_in_ms, long endtime_in_ms, String filename) {
         try {
             long fsize = Files.size(Paths.get(filename));
-            throughput(starttime_in_ms, endtime_in_ms, fsize);
+            return throughput(starttime_in_ms, endtime_in_ms, fsize);
         } catch (IOException e) {
+            log.warn("SLUBStoragePlugin.throughput, " + e.getMessage());
             /* do nothing */
         }
         return "(unknown) Bytes/s";
@@ -117,11 +129,13 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
      * @throws Exception
      */
     public boolean checkFixity(List<Fixity> fixities, String storedEntityIdentifier) throws Exception {
+        log.info("SLUBStoragePlugin.checkFixity() storedEntityIdentifier='" + storedEntityIdentifier + "'");
         String absolute_storedEntityIdentifier = getFullFilePath(storedEntityIdentifier);
-        log.info("SLUBStoragePlugin.checkFixity() storedEntityIdentifier='" + absolute_storedEntityIdentifier + "'");
+        contractAssertIsAbsolutePath(absolute_storedEntityIdentifier);
+        log.info("SLUBStoragePlugin.checkFixity() absolute_storedEntityIdentifier='" + absolute_storedEntityIdentifier + "'");
         // log.info("SLUBStoragePlugin.checkFixity() all fixities=" + fixities);
         if (fixities == null) {
-            log.warn("No fixity list provided");
+            log.warn("SLUBStoragePlugin.checkFixity() No fixity list provided");
             return true;
         }
         boolean result = true;
@@ -140,36 +154,36 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
      * @throws Exception
      */
     private boolean checkSpecificFixity(String absolute_storedEntityIdentifier, Fixity fixity) throws Exception {
+        contractAssertIsAbsolutePath(absolute_storedEntityIdentifier);
         String algorithm = fixity.getAlgorithm();
                     /* HINT: in past versions of Rosetta was a workaround for fixity.getAlgorithm() required,
                              a lowercase string was returned instead of the correct fixity code table entry */
-        log.info("SLUBStoragePlugin.checkFixity() getAlgorithm=" + algorithm);
+        log.info("SLUBStoragePlugin.checkSpecificFixity() absolute_storedEntityIdentifier='"+absolute_storedEntityIdentifier+"' getAlgorithm=" + algorithm);
         try {
-
             if (
                     (!Fixity.FixityAlgorithm.MD5.toString().equals(algorithm)) &&
                             (!Fixity.FixityAlgorithm.SHA1.toString().equals(algorithm)) &&
                             (!Fixity.FixityAlgorithm.SHA256.toString().equals(algorithm)) &&
                             (!Fixity.FixityAlgorithm.CRC32.toString().equals(algorithm))
             ) {
-                // log.info("SLUBStoragePlugin.checkFixity() call checkFixityByPlugin (" + fixity + "," + storedEntityIdentifier + ")");
+                log.info("SLUBStoragePlugin.checkSpecificFixity() call checkFixityByPlugin (" + fixity + "," + absolute_storedEntityIdentifier + ")");
                 return checkFixityByPlugin(fixity, absolute_storedEntityIdentifier);
             } else {
-                log.info("SLUBStoragePlugin.checkFixity() calcMD5|calcSHA1|calcCRC32|calcSHA256=true");
+                log.info("SLUBStoragePlugin.checkSpecificFixity() calcMD5|calcSHA1|calcCRC32|calcSHA256=true");
                 int checksummerAlgorithmIndex = getChecksummerAlgorithmIndex(algorithm);
-                log.info("SLUBStoragePlugin.checkFixity() checksummerAlgorithmIndex=" + checksummerAlgorithmIndex);
+                log.info("SLUBStoragePlugin.checkSpecificFixity() checksummerAlgorithmIndex=" + checksummerAlgorithmIndex);
                 if (checksummerAlgorithmIndex != -1) {
                     return checkFixityByBuiltin(fixity, absolute_storedEntityIdentifier, algorithm);
                 }
             }
         } catch (IOException e) {
-            log.error("SLUBStoragePlugin.checkFixity(), I/O error, " + e.getMessage());
+            log.error("SLUBStoragePlugin.checkSpecificFixity(), I/O error, " + e.getMessage());
             throw e; // let Rosetta know something broke, creates technical issue in workbench
         } catch (NoSuchAlgorithmException e) {
-            log.error("SLUBStoragePlugin.checkFixity(), missed Algorithm, " + e.getMessage());
+            log.error("SLUBStoragePlugin.checkSpecificFixity(), missed Algorithm, " + e.getMessage());
             throw e; // let Rosetta know something broke, creates technical issue in workbench
         } catch (Exception e) {
-            log.error("SLUBStoragePlugin.checkFixity(), unknown problem, " + e.getMessage());
+            log.error("SLUBStoragePlugin.checkSpecificFixity(), unknown problem, " + e.getMessage());
             throw e; // let Rosetta know something broke, creates technical issue in workbench
         }
         return false;
@@ -185,23 +199,37 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
      * @throws IOException if I/O error
      */
     private boolean checkFixityByBuiltin(Fixity fixity, String absolute_storedEntityIdentifier, String algorithm) throws NoSuchAlgorithmException, IOException {
+        log.info("SLUBStoragePlugin.checkFixityByBuiltin() absolute_storedEntityIdentifier='"+absolute_storedEntityIdentifier+"' algorithm=" + algorithm);
+        contractAssertIsAbsolutePath(absolute_storedEntityIdentifier);
         String oldValue = fixity.getValue();
-        log.info("SLUBStoragePlugin.checkFixity() getAlgorithm (2)=" + algorithm);
-        log.info("SLUBStoragePlugin.checkFixity() oldvalue=" + oldValue);
+        log.info("SLUBStoragePlugin.checkFixityByBuiltin() getAlgorithm (2)=" + algorithm);
+        log.info("SLUBStoragePlugin.checkFixityByBuiltin() oldvalue=" + oldValue);
         long starttime = System.currentTimeMillis();
-        InputStream is = retrieveEntity(absolute_storedEntityIdentifier);
+        String storedEntityIdentifier = relativePath(absolute_storedEntityIdentifier);
+        log.info("SLUBStoragePlugin.checkFixityByBuiltin() calculated storedEntityIdentifier=" + storedEntityIdentifier);
+        contractAssertIsRelativePath(storedEntityIdentifier);
+        InputStream is = retrieveEntity(storedEntityIdentifier);
         Checksummer checksummer = new Checksummer(is, true, true, true, true);
         fixity.setValue(checksummer.getChecksum(algorithm));
-        log.info("SLUBStoragePlugin.checkFixity() newvalue=" + fixity.getValue());
+        log.info("SLUBStoragePlugin.checkFixityByBuiltin() newvalue=" + fixity.getValue());
         fixity.setResult((oldValue == null) || (oldValue.equalsIgnoreCase(fixity.getValue())));
         boolean result = fixity.getResult();
         is.close();
         long endtime = System.currentTimeMillis();
-        var pathname = absolute_storedEntityIdentifier;
-        log.info("SLUBStoragePlugin.checkFixity() pathname='"+ pathname + "' result=" + result + " (builtin " + throughput(starttime, endtime, pathname)+ ")");
+        log.info("SLUBStoragePlugin.checkFixityByBuiltin() pathname='"+ absolute_storedEntityIdentifier + "' result=" + result + " (" + throughput(starttime, endtime, absolute_storedEntityIdentifier)+ ")");
         return result;
     }
 
+    String relativePath(String absolute_storedEntityIdentifier) {
+        var begin = getDirRoot().length();
+        var end = absolute_storedEntityIdentifier.length();
+        var rel = absolute_storedEntityIdentifier.substring(begin, end);
+        log.info("SLUBStoragePlugin.relativePath('"+ absolute_storedEntityIdentifier + "') -> DirRoot="+getDirRoot() + " begin=" + begin + " end=" + end + " rel='" + rel + "'");
+        assert(begin < end);
+        return rel;
+    }
+
+
     /** check fixity by calling its registered plugin
      *
      * @param fixity concrete fixity object
@@ -210,14 +238,14 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
      * @throws Exception to inform rosetta
      */
     private boolean checkFixityByPlugin(Fixity fixity, String absolute_storedEntityIdentifier) throws Exception {
-        assert( absolute_storedEntityIdentifier.startsWith( getDirRoot() ) );
-        log.info("SLUBStoragePlugin.checkFixityByPlugin() another fixity");
+        log.info("SLUBStoragePlugin.checkFixityByPlugin() another fixity, root=" + getDirRoot() + " absolute_storedEntityIdentifier=" + absolute_storedEntityIdentifier);
+        contractAssertIsAbsolutePath(absolute_storedEntityIdentifier);
         String pluginname = fixity.getPluginName();
         log.info("SLUBStoragePlugin.checkFixityByPlugin() pluginname=" + pluginname);
         // HINT: Workaround for Rosetta case 06472860 - Storage Plugin: Empty custom fixity plugin name breaks file updates [Rosetta 7.3.0.0]
         //       -> use fallback names in case fixity plugin name is missing
         if (pluginname == null || pluginname.length() == 0) {
-            log.warn("SLUBStoragePlugin failed to get pluginname, because it is empty. Possibly, there is no valid fixity type used or a CustomFixityPlugin missed");
+            log.warn("SLUBStoragePlugin.checkFixityByPlugin() failed to get pluginname, because it is empty. Possibly, there is no valid fixity type used or a CustomFixityPlugin missed");
             log.warn("SLUBStoragePlugin.checkFixityByPlugin() trying to use fallback table to determine plugin name");
             String algorithm = fixity.getAlgorithm();
             if ("SHA512".equals(algorithm)) {
@@ -230,7 +258,13 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
         String oldValue = fixity.getValue();
         log.info("SLUBStoragePlugin.checkFixityByPlugin() oldvalue=" + oldValue);
         long starttime = System.currentTimeMillis();
-        fixity.setValue(getChecksumUsingPlugin(absolute_storedEntityIdentifier, pluginname, oldValue));
+        String newValue = "should not occur";
+        try {
+            newValue = getChecksumUsingPlugin(absolute_storedEntityIdentifier, pluginname, oldValue);
+        } catch  (Exception e) {
+            log.error("SLUBStoragePlugin.checkFixityByPlugin() exception in getChecksumUsingPlugin("+absolute_storedEntityIdentifier + ", "+ pluginname + ", " + oldValue +"), " + e.getMessage() );
+        }
+        fixity.setValue(newValue);
         /* HINT: if plugin name is still empty a java.lang.NullPointerException gets thrown
                  Rosetta will handle it and let us know (creates technical issue in workbench)
          */
@@ -238,8 +272,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
         log.info("SLUBStoragePlugin.checkFixityByPlugin() newvalue=" + fixity.getValue());
         boolean result = fixity.getResult();
         long endtime = System.currentTimeMillis();
-        var pathname = absolute_storedEntityIdentifier;
-        log.info("SLUBStoragePlugin.checkFixityByPlugin() pathname='" + pathname + "' result=" + result + " (plugins " + throughput(starttime, endtime, pathname)+ ")");
+        log.info("SLUBStoragePlugin.checkFixityByPlugin() pathname='" + absolute_storedEntityIdentifier + "' result=" + result + " (plugins " + throughput(starttime, endtime, absolute_storedEntityIdentifier)+ ")");
         return result;
     }
 
@@ -252,6 +285,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
     {
         log.info("SLUBStoragePlugin.deleteEntity() storedEntityIdentifier='" + relative_storedEntityIdentifier + "'");
         var absolute_filename = getFullFilePath(relative_storedEntityIdentifier);
+
         File file = new File(absolute_filename);
         try
         {
@@ -259,7 +293,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
         }
         catch (Exception e)
         {
-            log.warn("SLUBStoragePlugin failed to delete entity with path: " + file.getPath(), e.getMessage());
+            log.warn("SLUBStoragePlugin.deleteEntity() failed to delete entity with path: " + file.getPath(), e.getMessage());
         }
         return true;
     }
@@ -278,11 +312,29 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
      */
     public String getFullFilePath(String storedEntityIdentifier)
     {
-        assert(! storedEntityIdentifier.startsWith( getDirRoot() ) );
         log.info("SLUBStoragePlugin.getFullFilePath() with '" + storedEntityIdentifier + "'");
         return getDirRoot() + storedEntityIdentifier;
     }
 
+    private void contractAssertIsRelativePath(String storedEntityIdentifier) throws IOException {
+        if ((storedEntityIdentifier.startsWith(getDirRoot()))) {
+            String message = "SLUBStoragePlugin.contractAssertIsRelativePath() storedEntityIdentifier='" + storedEntityIdentifier + "' should be relative, but starts with ROOT '"+getDirRoot()+"'";
+            log.error(message);
+            throw new IOException(message);
+        }
+    }
+    private void contractAssertIsAbsolutePath(String absolute_storedEntityIdentifier) throws IOException {
+        if ((!absolute_storedEntityIdentifier.startsWith(getDirRoot()))) {
+            String message = "SLUBStoragePlugin.contractAssertIsAbsolutePath() absolute_storedEntityIdentifier='" + absolute_storedEntityIdentifier + "' starts not with ROOT '" + getDirRoot() + "'";
+            log.error(message);
+            throw new IOException(message);
+        }
+        if ((absolute_storedEntityIdentifier.startsWith(getDirRoot() + getDirRoot()))) {
+            String message = "SLUBStoragePlugin.contractAssertIsAbsolutePath() absolute_storedEntityIdentifier='"+ absolute_storedEntityIdentifier + "' starts with ROOT '" + getDirRoot() + "' twice!";
+            log.error(message);
+            throw new IOException(message);
+        }
+    }
     /**
      * retrieveEntity
      * @param storedEntityIdentifier as relative filepath
@@ -292,10 +344,12 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
     public InputStream retrieveEntity(String storedEntityIdentifier)
             throws IOException
     {
-        log.info("SLUBStoragePlugin.retrieveEntity() with '" + storedEntityIdentifier + "'");
+        log.info("SLUBStoragePlugin.retrieveEntity() with storedEntityIdentifier '" + storedEntityIdentifier + "'");
+        contractAssertIsRelativePath(storedEntityIdentifier);
         // TODO: 64k (1MB) buffer set
         // OLD, without buffering, but working: InputStream foo =  java.nio.file.Files.newInputStream( Paths.get( pathname));
         var absolute_filename = getFullFilePath(storedEntityIdentifier);
+        contractAssertIsAbsolutePath(absolute_filename);
         var absolute_path = Paths.get(absolute_filename);
         var is = java.nio.file.Files.newInputStream( absolute_path );
         return new BufferedInputStream( is , getBlockSize());
@@ -311,7 +365,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
      */
     public byte[] retrieveEntityByRange(String storedEntityIdentifier, long start, long end) throws Exception
     {
-        log.info("SLUBStoragePlugin.retrieveEntitybyRange() with '" + storedEntityIdentifier + "' start=" + start + " end=" + end);
+        log.info("SLUBStoragePlugin.retrieveEntitybyRange() with storedEntityIdentifier='" + storedEntityIdentifier + "' start=" + start + " end=" + end);
         /* try-with-ressource block, no close if failed needed */
         var absolute_filename = getFullFilePath(storedEntityIdentifier);
         try (RandomAccessFile file = new RandomAccessFile(absolute_filename, "r"))
@@ -358,15 +412,18 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
         {
             destFilePath = existsDescPath;
             /* destFilePath is relative, checkfixity expects absolute */
+            log.info("SLUBStoragePlugin.storeEntity() calling checkFixity(storedEntityMetadata.getFixities(), '"+destFilePath+");");
             isCopyFileNeeded = !checkFixity(storedEntityMetadata.getFixities(), destFilePath);
         }
-        log.debug("SLUBStoragePlugin.storeEntity() destFilePath='" + destFilePath + "'");
+        log.info("SLUBStoragePlugin.storeEntity() destFilePath='" + destFilePath + "'");
         Map<String, String> paths = getStoreEntityIdentifier(storedEntityMetadata, destFilePath);
         String storedEntityIdentifier = paths.get("relativeDirectoryPath");
-        log.debug("SLUBStoragePlugin.storeEntity() storedEntityIdentifier='" + storedEntityIdentifier + "'");
+        contractAssertIsRelativePath(storedEntityIdentifier);
+        log.info("SLUBStoragePlugin.storeEntity() storedEntityIdentifier='" + storedEntityIdentifier + "'");
         String absolute_destFilePath = paths.get("destFilePath");
-        log.debug("SLUBStoragePlugin.storeEntity() destFilePath (2)='" + absolute_destFilePath + "'");
-        log.debug("SLUBStoragePlugin.storeEntity() isCopyFileNeeded='" + isCopyFileNeeded + "'");
+        contractAssertIsAbsolutePath(absolute_destFilePath);
+        log.info("SLUBStoragePlugin.storeEntity() destFilePath (2)='" + absolute_destFilePath + "'");
+        log.info("SLUBStoragePlugin.storeEntity() isCopyFileNeeded='" + isCopyFileNeeded + "'");
         if (isCopyFileNeeded)
         {
             if (canHandleSourcePath(storedEntityMetadata.getCurrentFilePath()))
@@ -376,7 +433,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
                     is.close();
                 }
                 copyStream(storedEntityMetadata, absolute_destFilePath);
-                log.info("SLUBStoragePlugin.storeEntity() try copy (copyStream) was successfull");
+                log.info("SLUBStoragePlugin.storeEntity() try copy (copyStream(storedEntityMetadata, '" + absolute_destFilePath + "')) was successfull");
             }
             else
             {
@@ -391,15 +448,15 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
                     long starttime = System.currentTimeMillis();
                     IOUtil.copy(is, output, getBlockSize());
                     long endtime = System.currentTimeMillis();
-                    log.info("SLUBStoragePlugin.storeEntity() try copy (IOUtil.copy) was successfull (" + throughput(starttime, endtime, absolute_destFilePath)+ ")" );
+                    log.info("SLUBStoragePlugin.storeEntity() try copy (IOUtil.copy(is, '"+absolute_destFilePath+"', blocksize) was successfull (" + throughput(starttime, endtime, absolute_destFilePath)+ ")" );
                 }
             }
             if (!checkFixity(storedEntityMetadata.getFixities(), storedEntityIdentifier)) {
-                log.info("SLUBStoragePlugin.storeEntity() checkFixity failed");
+                log.info("SLUBStoragePlugin.storeEntity() called checkFixity(fixities, '"+storedEntityIdentifier+"') failed");
                 return null;
             }
         }
-        log.debug("SLUBStoragePlugin.storeEntity() storedEntityIdentifier (2)='" + storedEntityIdentifier + "'");
+        log.info("SLUBStoragePlugin.storeEntity() storedEntityIdentifier (2)='" + storedEntityIdentifier + "'");
         return storedEntityIdentifier;
     }
 
@@ -440,7 +497,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
             FileUtil.copyFile(srcPath, destPath);
             saveDestPathsTmpFile(iePid, pid, destPath);
             long endtime = System.currentTimeMillis();
-            log.info("SLUBStoragePlugin.copyStream(), copyFile was successful (" + throughput(starttime, endtime, srcPath) + ")");
+            log.info("SLUBStoragePlugin.copyStream(), copyFile('"+srcPath+"','" + destPath + "') was successful (" + throughput(starttime, endtime, srcPath) + ")");
         }
     }
     protected String getFilePathInDescIfExists(StoredEntityMetaData storedEntityMetadata)
@@ -451,7 +508,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
         }
         String tmpFilePath = getTempStorageDirectory(false) + "destPath";
         String existsDescPath = StorageUtil.readDestPathFromTmpFile(storedEntityMetadata.getIePid(), tmpFilePath, storedEntityMetadata.getEntityPid());
-        log.debug("SLUBStoragePlugin.getFilePathInDescIfExists() existsDescPath='" + existsDescPath + "'");
+        log.info("SLUBStoragePlugin.getFilePathInDescIfExists() existsDescPath='" + existsDescPath + "'");
         return existsDescPath;
     }
 
@@ -518,11 +575,14 @@ public class SLUBStoragePlugin extends AbstractStorageHandler {
         {
             File destFile = getStreamDirectory(relativeDirectoryPath, fileName);
             destFilePath = destFile.getAbsolutePath();
+
         }
-        log.debug("destFilePath (2)='" + destFilePath + "'");
+        contractAssertIsAbsolutePath(destFilePath);
+        log.info("destFilePath (2)='" + destFilePath + "'");
         paths.put("destFilePath", destFilePath);
-        // paths.put("relativeDirectoryPath", (relativeDirectoryPath + getNextDir(destFilePath) + File.separator + fileName));
-        paths.put("relativeDirectoryPath", (relativeDirectoryPath + File.separator + fileName));
+        String relativePath = relativeDirectoryPath + File.separator + fileName;
+        contractAssertIsRelativePath(relativePath);
+        paths.put("relativeDirectoryPath", relativePath);
         return paths;
     }
     /** copied from NFS Storage Plugin, enhanced with debugging info,
diff --git a/java/org/slub/rosetta/dps/repository/plugin/storage/nfs/TestSLUBStoragePlugin.java b/java/org/slub/rosetta/dps/repository/plugin/storage/nfs/TestSLUBStoragePlugin.java
index 1b1c16c..4d35250 100644
--- a/java/org/slub/rosetta/dps/repository/plugin/storage/nfs/TestSLUBStoragePlugin.java
+++ b/java/org/slub/rosetta/dps/repository/plugin/storage/nfs/TestSLUBStoragePlugin.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 
+import static java.nio.file.Path.of;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
@@ -38,7 +39,7 @@ public class TestSLUBStoragePlugin {
   @Before
   public void setUp() throws IOException {
     testroot = Files.createTempDirectory("testslubstorage");
-    Files.createFile(Path.of(testroot.toAbsolutePath().toString() + "/foo"));
+    Files.createFile(of(testroot.toAbsolutePath().toString() + "/foo"));
     mock = new SLUBStoragePlugin();
     HashMap<String, String> map = new HashMap<String,String> ();
     map.put("DIR_ROOT", testroot.toAbsolutePath().toString());
@@ -66,10 +67,15 @@ public class TestSLUBStoragePlugin {
       assertTrue("checkFixity", result);
     }
     catch (Exception e) {
-      assertEquals("checkFixity", "foo", e);
+      assertEquals("checkFixity", "foo", e.getMessage());
     }
   }
 
+  @Test
+  public void relativePath() {
+    String absolute = testroot.toAbsolutePath().toString()+"/2022";
+    assertEquals("relativePath", "/2022", mock.relativePath(absolute));
+  }
   @Test
   public void getFullFilePath() {
     assertEquals( "getFullFilePath", testroot.toAbsolutePath().toString()+"/2022", mock.getFullFilePath("/2022"));
@@ -80,7 +86,18 @@ public class TestSLUBStoragePlugin {
       InputStream is = mock.retrieveEntity("/foo");
       assertTrue("retrieveEntity", true);
     } catch (Exception e) {
-      assertEquals("retrieveEntity", "", e);
+      assertEquals("retrieveEntity", "", e.getMessage());
+    }
+  }
+  @Test
+  public void retrieveEntity_dirroot() {
+    try {
+      InputStream is = mock.retrieveEntity(testroot.toAbsolutePath().toString() + "/foo");
+      assertTrue("retrieveEntity", true);
+    } catch (IllegalArgumentException e) {
+      assertEquals("retrieveEntity", "", e.getMessage());
+    } catch (IOException e) {
+      assertTrue("retrieveEntity", e.getMessage().contains("should be relative, but starts with ROOT"));
     }
   }
   @Test
-- 
GitLab