From 2b1e5d01ece4cffa36876ecefc6b9a7e25df6015 Mon Sep 17 00:00:00 2001 From: Andreas Romeyke <andreas.romeyke@slub-dresden.de> Date: Tue, 4 Apr 2023 15:16:36 +0200 Subject: [PATCH] - refactoring, added inner class AbsolutePath to be typesafe - fixed bug, checkFixity() expects a storedEntityIdentifier --- .../plugin/storage/nfs/SLUBStoragePlugin.java | 124 +++++++++--------- .../storage/nfs/TestSLUBStoragePlugin.java | 7 +- 2 files changed, 64 insertions(+), 67 deletions(-) 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 e4666a0..8400881 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 @@ -79,13 +79,31 @@ import java.util.Optional; public class SLUBStoragePlugin extends AbstractStorageHandler { private static final ExLogger log = ExLogger.getExLogger(SLUBStoragePlugin.class); - private String getDirRoot () { + protected String getDirRoot() { String path = parameters.get("DIR_ROOT"); if (null == path) { log.error("Could not retrieve DIR_ROOT"); } return path; } + protected class AbsolutePath { + public AbsolutePath( String f) throws IOException { + if ((!f.startsWith(getDirRoot()))) { + String message = "SLUBStoragePlugin.AbsolutePath ='" + f + "' starts not with ROOT '" + getDirRoot() + "'"; + log.error(message); + throw new IOException(message); + } + if ((f.startsWith(getDirRoot() + getDirRoot()))) { + String message = "SLUBStoragePlugin.AbsolutePath ='"+ f + "' starts with ROOT '" + getDirRoot() + "' twice!"; + log.error(message); + throw new IOException(message); + } + filestring = f; + } + public String filestring; + } + + private int getBlockSize () { int blockSize = 32*1024; String blocksizeStr = this.parameters.get("BLOCK_SIZE"); @@ -108,9 +126,9 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { return filehandlingMethod; } - private String throughput(long starttime_in_ms, long endtime_in_ms, String filename) { + private String throughput(long starttime_in_ms, long endtime_in_ms, AbsolutePath filename) { try { - long fsize = Files.size(Paths.get(filename)); + long fsize = Files.size(Paths.get(filename.filestring)); return throughput(starttime_in_ms, endtime_in_ms, fsize); } catch (IOException e) { log.warn("SLUBStoragePlugin.throughput, " + e.getMessage()); @@ -151,8 +169,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { */ public boolean checkFixity(List<Fixity> fixities, String storedEntityIdentifier) throws IOException{ //log.debug("SLUBStoragePlugin.checkFixity() storedEntityIdentifier='" + storedEntityIdentifier + "'"); - String absolute_storedEntityIdentifier = getFullFilePath(storedEntityIdentifier); - contractAssertIsAbsolutePath(absolute_storedEntityIdentifier); + AbsolutePath absolute_storedEntityIdentifier = new AbsolutePath(getFullFilePath(storedEntityIdentifier)); //log.debug("SLUBStoragePlugin.checkFixity() absolute_storedEntityIdentifier='" + absolute_storedEntityIdentifier + "'"); if (null==fixities) { log.warn("SLUBStoragePlugin.checkFixity() No fixity list provided"); @@ -179,8 +196,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { * @return true if valid otherwise false * @throws Exception */ - private boolean checkSpecificFixity(String absolute_storedEntityIdentifier, Fixity fixity) throws IOException, NoSuchAlgorithmException { - contractAssertIsAbsolutePath(absolute_storedEntityIdentifier); + private boolean checkSpecificFixity(AbsolutePath absolute_storedEntityIdentifier, Fixity fixity) throws IOException, NoSuchAlgorithmException { 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 */ @@ -225,9 +241,8 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { * @throws NoSuchAlgorithmException if algorithm is unknown * @throws IOException if I/O error */ - private boolean checkFixityByBuiltin(Fixity fixity, String absolute_storedEntityIdentifier, String algorithm) throws NoSuchAlgorithmException, IOException { + private boolean checkFixityByBuiltin(Fixity fixity, AbsolutePath absolute_storedEntityIdentifier, String algorithm) throws NoSuchAlgorithmException, IOException { //log.debug("SLUBStoragePlugin.checkFixityByBuiltin() absolute_storedEntityIdentifier='"+absolute_storedEntityIdentifier+"' algorithm=" + algorithm); - contractAssertIsAbsolutePath(absolute_storedEntityIdentifier); String oldValue = fixity.getValue(); //log.debug("SLUBStoragePlugin.checkFixityByBuiltin() getAlgorithm (2)=" + algorithm); //log.debug("SLUBStoragePlugin.checkFixityByBuiltin() oldvalue=" + oldValue); @@ -254,10 +269,10 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { return result; } - String relativePath(String absolute_storedEntityIdentifier) { + String relativePath(AbsolutePath absolute_storedEntityIdentifier) { var begin = getDirRoot().length(); - var end = absolute_storedEntityIdentifier.length(); - var rel = absolute_storedEntityIdentifier.substring(begin, end); + var end = absolute_storedEntityIdentifier.filestring.length(); + var rel = absolute_storedEntityIdentifier.filestring.substring(begin, end); //log.debug("SLUBStoragePlugin.relativePath('"+ absolute_storedEntityIdentifier + "') -> DirRoot="+getDirRoot() + " begin=" + begin + " end=" + end + " rel='" + rel + "'"); assert(begin < end); return rel; @@ -271,9 +286,8 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { * @return true if valid, otherwise false * @throws Exception to inform rosetta */ - private boolean checkFixityByPlugin(Fixity fixity, String absolute_storedEntityIdentifier) throws IOException { + private boolean checkFixityByPlugin(Fixity fixity, AbsolutePath absolute_storedEntityIdentifier) { //log.debug("SLUBStoragePlugin.checkFixityByPlugin() another fixity, root=" + getDirRoot() + " absolute_storedEntityIdentifier=" + absolute_storedEntityIdentifier); - contractAssertIsAbsolutePath(absolute_storedEntityIdentifier); String pluginname = fixity.getPluginName(); //log.debug("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] @@ -294,9 +308,9 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { long starttime = System.currentTimeMillis(); String newValue = "should not occur"; try { - newValue = getChecksumUsingPlugin(absolute_storedEntityIdentifier, pluginname, oldValue); + newValue = getChecksumUsingPlugin(absolute_storedEntityIdentifier.filestring, pluginname, oldValue); } catch (Exception e) { - log.error("SLUBStoragePlugin.checkFixityByPlugin() exception in getChecksumUsingPlugin("+absolute_storedEntityIdentifier + ", "+ pluginname + ", " + oldValue +"), " + e.getMessage() ); + log.error("SLUBStoragePlugin.checkFixityByPlugin() exception in getChecksumUsingPlugin("+absolute_storedEntityIdentifier.filestring + ", "+ pluginname + ", " + oldValue +"), " + e.getMessage() ); } fixity.setValue(newValue); /* HINT: if plugin name is still empty a java.lang.NullPointerException gets thrown @@ -344,13 +358,18 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { /** * getFullFilePath + * * @param storedEntityIdentifier - relative filepath * @return absolute filepath */ public String getFullFilePath(String storedEntityIdentifier) { //log.debug("SLUBStoragePlugin.getFullFilePath() with '" + storedEntityIdentifier + "'"); - return getDirRoot() + storedEntityIdentifier; + try { + return new AbsolutePath( getDirRoot() + storedEntityIdentifier ).filestring; + } catch (IOException e) { + throw new RuntimeException(e); + } } private void contractAssertIsRelativePath(String storedEntityIdentifier) throws IOException { @@ -360,18 +379,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { 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 @@ -384,7 +392,6 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { log.info("SLUBStoragePlugin.retrieveEntity() with storedEntityIdentifier '" + storedEntityIdentifier + "'"); contractAssertIsRelativePath(storedEntityIdentifier); 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()); @@ -435,20 +442,19 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { throws IOException { log.info("SLUBStoragePlugin.storeEntity()"); - String nullOrAbsoluteDestFilePath = getAbsolutePathInDescIfExists(storedEntityMetadata); + AbsolutePath nullOrAbsoluteDestFilePath = getAbsolutePathInDescIfExists(storedEntityMetadata); //log.debug("SLUBStoragePlugin.storeEntity() existsDescPath='" + existsDescPath + "'"); boolean isCopyFileNeeded = true; + Map<String, String> paths = getStoreEntityIdentifier(storedEntityMetadata, nullOrAbsoluteDestFilePath); + String storedEntityIdentifier = paths.get("relativeDirectoryPath"); + contractAssertIsRelativePath(storedEntityIdentifier); if (nullOrAbsoluteDestFilePath != null) { - isCopyFileNeeded = !checkFixity(storedEntityMetadata.getFixities(), nullOrAbsoluteDestFilePath); + isCopyFileNeeded = !checkFixity(storedEntityMetadata.getFixities(), storedEntityIdentifier); } //log.debug("SLUBStoragePlugin.storeEntity() destFilePath='" + destFilePath + "'"); - Map<String, String> paths = getStoreEntityIdentifier(storedEntityMetadata, nullOrAbsoluteDestFilePath); - String storedEntityIdentifier = paths.get("relativeDirectoryPath"); - contractAssertIsRelativePath(storedEntityIdentifier); //log.debug("SLUBStoragePlugin.storeEntity() storedEntityIdentifier='" + storedEntityIdentifier + "'"); - String absoluteDestFilePath = paths.get("destFilePath"); - contractAssertIsAbsolutePath(absoluteDestFilePath); + AbsolutePath absoluteDestFilePath = new AbsolutePath(paths.get("destFilePath")); //log.debug("SLUBStoragePlugin.storeEntity() destFilePath (2)='" + absolute_destFilePath + "'"); //log.debug("SLUBStoragePlugin.storeEntity() isCopyFileNeeded='" + isCopyFileNeeded + "'"); if (isCopyFileNeeded) @@ -470,7 +476,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { log.warn("SLUBStoragePlugin.storeEntity() InputStream is null"); return null; } - try (OutputStream output = java.nio.file.Files.newOutputStream( Paths.get( absoluteDestFilePath))) + try (OutputStream output = java.nio.file.Files.newOutputStream( Paths.get( absoluteDestFilePath.filestring))) { var blocksize = getBlockSize(); long starttime = System.currentTimeMillis(); @@ -494,26 +500,26 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { * @param destination * @throws IOException */ - private void copyFile(String source, String destination) throws IOException { + private void copyFile(String source, AbsolutePath destination) throws IOException { long starttime = System.currentTimeMillis(); if (!source.toLowerCase().trim().startsWith("http")) { /* simpleFilecopy, see https://www.digitalocean.com/community/tutorials/java-copy-file */ try ( FileChannel sourceChannel = new FileInputStream(source).getChannel(); - FileChannel destChannel = new FileOutputStream(destination).getChannel() + FileChannel destChannel = new FileOutputStream(destination.filestring).getChannel() ) { destChannel.transferFrom(sourceChannel, 0, sourceChannel.size()); } } else { InputStream input = FileTransferUtil.getUrlContent(source); - FileOutputStream output = new FileOutputStream(destination); + FileOutputStream output = new FileOutputStream(destination.filestring); IOUtil.copy(input, output, getBlockSize()); IOUtil.shutdownStream(input); IOUtil.shutdownStream(output); } long endtime = System.currentTimeMillis(); - log.info("SLUBStoragePlugin.copyFile (" + source + ", " + destination + ") was successfull (" + throughput(starttime, endtime, destination) + ")"); + log.info("SLUBStoragePlugin.copyFile (" + source + ", " + destination.filestring + ") was successfull (" + throughput(starttime, endtime, destination) + ")"); } - protected void copyStream(StoredEntityMetaData storedEntityMetadata, String absoluteDestPath) + protected void copyStream(StoredEntityMetaData storedEntityMetadata, AbsolutePath absoluteDestPath) throws IOException { log.info("SLUBStoragePlugin.copyStream()"); @@ -526,7 +532,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { //log.debug("SLUBStoragePlugin.copyStream() pid='" + pid + "'"); String iePid = storedEntityMetadata.getIePid(); //log.debug("SLUBStoragePlugin.copyStream() iePid='" + iePid + "'"); - String attr = "('"+srcPath+"','" + absoluteDestPath + "')"; + String attr = "('"+srcPath+"','" + absoluteDestPath.filestring + "')"; if ("copy".equalsIgnoreCase(filesHandlingMethod)) { // FileUtil.copyFile(srcPath, destPath); copyFile(srcPath, absoluteDestPath); @@ -535,16 +541,16 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { } else if ("move".equalsIgnoreCase(filesHandlingMethod)) { File canonicalSrcFile = getCanonicalFile(srcPath); assert canonicalSrcFile != null; - FileUtil.moveFile(canonicalSrcFile, new File(absoluteDestPath)); + FileUtil.moveFile(canonicalSrcFile, new File(absoluteDestPath.filestring)); saveAbsoluteDestPathsTmpFile(storedEntityMetadata, absoluteDestPath); log.info("SLUBStoragePlugin.copyStream(), move"+attr+" was successful"); } else if ("soft_link".equalsIgnoreCase(filesHandlingMethod)) { - softLink(srcPath, absoluteDestPath); + softLink(srcPath, absoluteDestPath.filestring); log.info("SLUBStoragePlugin.copyStream(), softlink"+attr+" was successful"); } else if ("hard_link".equalsIgnoreCase(filesHandlingMethod)) { - hardLink(srcPath, absoluteDestPath); + hardLink(srcPath, absoluteDestPath.filestring); log.info("SLUBStoragePlugin.copyStream(), hardlink"+attr+" was successful"); } else { @@ -553,14 +559,14 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { throw new IOException(msg); } } - protected String getAbsolutePathInDescIfExists(StoredEntityMetaData storedEntityMetadata) throws IOException { + protected AbsolutePath getAbsolutePathInDescIfExists(StoredEntityMetaData storedEntityMetadata) throws IOException { log.info("SLUBStoragePlugin.getFilePathInDescIfExists()"); if (storedEntityMetadata.getIePid() == null) { return null; } - String existsAbsoluteDescPath = loadAbsoluteDestPathsTmpFile(storedEntityMetadata); + return loadAbsoluteDestPathsTmpFile(storedEntityMetadata); //log.debug("SLUBStoragePlugin.getFilePathInDescIfExists() existsDescPath='" + existsDescPath + "'"); - return existsAbsoluteDescPath; + } @@ -614,7 +620,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { } /** copied from NFS Storage Plugin, enhanced with debugging info, {@inheritDoc} */ - private Map<String, String> getStoreEntityIdentifier(StoredEntityMetaData storedEntityMetadata, String absoluteDestFilePath) throws IOException { + private Map<String, String> getStoreEntityIdentifier(StoredEntityMetaData storedEntityMetadata, AbsolutePath absoluteDestFilePath) throws IOException { log.info("SLUBStoragePlugin.getStoreEntityIdentifier() destFilePath='" + absoluteDestFilePath +"'"); Map<String, String> paths = new HashMap<>(); //log.debug("(1) storedEntityMetadata is null?" + (null == storedEntityMetadata)); @@ -626,12 +632,10 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { if (absoluteDestFilePath == null) { File destFile = getStreamDirectory(relativeDirectoryPath, fileName); - absoluteDestFilePath = destFile.getAbsolutePath(); - + absoluteDestFilePath = new AbsolutePath(destFile.getAbsolutePath()); } - contractAssertIsAbsolutePath(absoluteDestFilePath); //log.debug("destFilePath (2)='" + destFilePath + "'"); - paths.put("destFilePath", absoluteDestFilePath); + paths.put("destFilePath", absoluteDestFilePath.filestring); String relativePath = relativeDirectoryPath + File.separator + fileName; contractAssertIsRelativePath(relativePath); paths.put("relativeDirectoryPath", relativePath); @@ -745,9 +749,8 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { * @param storedEntityMetadata * @param absolutePath */ - private void saveAbsoluteDestPathsTmpFile(StoredEntityMetaData storedEntityMetadata, String absolutePath) throws IOException { + private void saveAbsoluteDestPathsTmpFile(StoredEntityMetaData storedEntityMetadata, AbsolutePath absolutePath) { log.info("SLUBStoragePlugin.saveDestPathsTmpFile()"); - contractAssertIsAbsolutePath(absolutePath); String tmpFilePath = getTempStorageDirectory(false) + "destPath"; //log.debug("SLUBStoragePlugin.saveDestPathsTmpFile tmpFilePath='" + tmpFilePath + "'"); File destPathDir = new File(getTempStorageDirectory(false) + "destPath" + File.separator); @@ -758,7 +761,7 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { log.error("SLUBStoragePlugin.saveDestPathsTmpFile() destPathdir='" + destPathDir + "' could not be created"); } } - StorageUtil.saveDestPathToTmpFile(storedEntityMetadata.getIePid(), tmpFilePath, storedEntityMetadata.getEntityPid(), absolutePath); + StorageUtil.saveDestPathToTmpFile(storedEntityMetadata.getIePid(), tmpFilePath, storedEntityMetadata.getEntityPid(), absolutePath.filestring); } /** @@ -766,10 +769,9 @@ public class SLUBStoragePlugin extends AbstractStorageHandler { * @param storedEntityMetadata * @return absolute path */ - private String loadAbsoluteDestPathsTmpFile(StoredEntityMetaData storedEntityMetadata) throws IOException { + private AbsolutePath loadAbsoluteDestPathsTmpFile(StoredEntityMetaData storedEntityMetadata) throws IOException { String tmpFilePath = getTempStorageDirectory(false) + "destPath"; String absolutePath = StorageUtil.readDestPathFromTmpFile(storedEntityMetadata.getIePid(), tmpFilePath, storedEntityMetadata.getEntityPid()); - contractAssertIsAbsolutePath(absolutePath); - return absolutePath; + return new AbsolutePath(absolutePath); } } 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 02b433c..e585d40 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 @@ -72,11 +72,6 @@ public class TestSLUBStoragePlugin { } } - @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")); @@ -125,7 +120,7 @@ public class TestSLUBStoragePlugin { InputStreamReader isr = new InputStreamReader(ioStream); char[] charArray = new char[(int)file.length()]; isr.read(charArray); - String iemets = new String(charArray); + String iemets = String.valueOf(charArray); try { DnxDocument dnx = DnxDocumentFactory.getInstance().createDnxDocument(false); dnx.setDocumentXml(iemets); -- GitLab