From de06851e56793c612315ec0388b3456679176afa Mon Sep 17 00:00:00 2001 From: Dou Mok Date: Wed, 13 Nov 2024 12:59:30 -0800 Subject: [PATCH 1/5] Revise 'NonMatchingChecksumException' class to have a 'hexDigests' attribute --- .../exceptions/NonMatchingChecksumException.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/dataone/hashstore/exceptions/NonMatchingChecksumException.java b/src/main/java/org/dataone/hashstore/exceptions/NonMatchingChecksumException.java index 3704144e..3bc23c4b 100644 --- a/src/main/java/org/dataone/hashstore/exceptions/NonMatchingChecksumException.java +++ b/src/main/java/org/dataone/hashstore/exceptions/NonMatchingChecksumException.java @@ -1,13 +1,21 @@ package org.dataone.hashstore.exceptions; +import java.util.Map; + /** * An exception thrown when a checksum does not match what is expected. */ public class NonMatchingChecksumException extends IllegalArgumentException { - public NonMatchingChecksumException(String message) { + private final Map hexDigests; + + public NonMatchingChecksumException(String message, Map checksumMap) { super(message); + this.hexDigests = checksumMap; } + public Map getHexDigests() { + return hexDigests; + } } From 51a7048632253121fa0c09c190aa7abe6b544495 Mon Sep 17 00:00:00 2001 From: Dou Mok Date: Wed, 13 Nov 2024 13:00:54 -0800 Subject: [PATCH 2/5] Include hexDigests when 'NonMatchingChecksumException' is thrown in 'FileHashStore' and 'FileHashStoreLinks' --- .../dataone/hashstore/filehashstore/FileHashStore.java | 8 ++++---- .../hashstore/hashstoreconverter/FileHashStoreLinks.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/dataone/hashstore/filehashstore/FileHashStore.java b/src/main/java/org/dataone/hashstore/filehashstore/FileHashStore.java index 4bcccf95..65edeb45 100644 --- a/src/main/java/org/dataone/hashstore/filehashstore/FileHashStore.java +++ b/src/main/java/org/dataone/hashstore/filehashstore/FileHashStore.java @@ -859,7 +859,7 @@ public void deleteIfInvalidObject( + ". Actual checksum calculated: " + digestFromHexDigests + " (algorithm: " + checksumAlgorithm + ")"; logFileHashStore.error(errMsg); - throw new NonMatchingChecksumException(errMsg); + throw new NonMatchingChecksumException(errMsg, hexDigests); } // Validate size if (objInfoRetrievedSize != objSize) { @@ -1269,7 +1269,7 @@ protected void validateTmpObject( String errMsg = baseErrMsg + ". Failed to delete tmpFile: " + tmpFile + ". " + ge.getMessage(); logFileHashStore.error(errMsg); - throw new NonMatchingChecksumException(errMsg); + throw new NonMatchingChecksumException(errMsg, hexDigests); } String errMsg = baseErrMsg + ". tmpFile has been deleted: " + tmpFile; logFileHashStore.error(errMsg); @@ -1285,12 +1285,12 @@ protected void validateTmpObject( String errMsg = baseErrMsg + ". Failed to delete tmpFile: " + tmpFile + ". " + ge.getMessage(); logFileHashStore.error(errMsg); - throw new NonMatchingChecksumException(errMsg); + throw new NonMatchingChecksumException(errMsg, hexDigests); } String errMsg = baseErrMsg + ". tmpFile has been deleted: " + tmpFile; logFileHashStore.error(errMsg); - throw new NonMatchingChecksumException(errMsg); + throw new NonMatchingChecksumException(errMsg, hexDigests); } } } diff --git a/src/main/java/org/dataone/hashstore/hashstoreconverter/FileHashStoreLinks.java b/src/main/java/org/dataone/hashstore/hashstoreconverter/FileHashStoreLinks.java index 8a959592..ff89c815 100644 --- a/src/main/java/org/dataone/hashstore/hashstoreconverter/FileHashStoreLinks.java +++ b/src/main/java/org/dataone/hashstore/hashstoreconverter/FileHashStoreLinks.java @@ -100,7 +100,7 @@ public ObjectMetadata storeHardLink( + " calculated: " + checksumToMatch + " for pid: " + pid + " and checksum" + " algorithm: " + checksumAlgorithm; logFileHashStoreLinks.error(errMsg); - throw new NonMatchingChecksumException(errMsg); + throw new NonMatchingChecksumException(errMsg, hexDigests); } // Gather the elements to form the permanent address From 632147504d9f298c135e2d197954bab5c2ff711e Mon Sep 17 00:00:00 2001 From: Dou Mok Date: Wed, 13 Nov 2024 13:01:52 -0800 Subject: [PATCH 3/5] Add new junit test to confirm hexDigests are included when 'NonMatchingChecksumException' is thrown and fix innacurate javadoc for a junit test --- .../FileHashStoreInterfaceTest.java | 35 ++++++++++++++++++- .../FileHashStoreProtectedTest.java | 4 +-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreInterfaceTest.java b/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreInterfaceTest.java index 7bc157fb..32cc50d3 100644 --- a/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreInterfaceTest.java +++ b/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreInterfaceTest.java @@ -365,7 +365,7 @@ public void storeObject_correctChecksumValue() throws Exception { */ @Test public void storeObject_incorrectChecksumValue() { - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(NonMatchingChecksumException.class, () -> { // Get test file to "upload" String pid = "jtao.1700.1"; Path testDataFile = testData.getTestFile(pid); @@ -379,6 +379,39 @@ public void storeObject_incorrectChecksumValue() { }); } + /** + * Verify exception contains hexDigests when NonMatchingChecksumException is thrown + */ + @Test + public void storeObject_nonMatchingChecksumException_hexDigestsIncluded() throws Exception { + // Get test file to "upload" + String pid = "jtao.1700.1"; + Path testDataFile = testData.getTestFile(pid); + + String checksumIncorrect = + "aaf9b6c88f1f458e410c30c351c6384ea42ac1b5ee1f8430d3e365e43b78a38a"; + + try (InputStream dataStream = Files.newInputStream(testDataFile)) { + try { + fileHashStore.storeObject(dataStream, pid, null, checksumIncorrect, "SHA-256", -1); + + } catch (NonMatchingChecksumException nmce) { + Map hexDigestsRetrieved = nmce.getHexDigests(); + + String md5 = testData.pidData.get(pid).get("md5"); + String sha1 = testData.pidData.get(pid).get("sha1"); + String sha256 = testData.pidData.get(pid).get("sha256"); + String sha384 = testData.pidData.get(pid).get("sha384"); + String sha512 = testData.pidData.get(pid).get("sha512"); + assertEquals(md5, hexDigestsRetrieved.get("MD5")); + assertEquals(sha1, hexDigestsRetrieved.get("SHA-1")); + assertEquals(sha256, hexDigestsRetrieved.get("SHA-256")); + assertEquals(sha384, hexDigestsRetrieved.get("SHA-384")); + assertEquals(sha512, hexDigestsRetrieved.get("SHA-512")); + } + } + } + /** * Verify exception thrown when checksum is empty and algorithm supported */ diff --git a/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreProtectedTest.java b/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreProtectedTest.java index 0bd99379..a36678b7 100644 --- a/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreProtectedTest.java +++ b/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreProtectedTest.java @@ -643,8 +643,8 @@ public void validateTmpObject_validationRequested_matchingChecksum() throws Exce } /** - * Confirm validateTmpObject does not throw exception when requested to validate checksums with - * good values, and that the tmpFile passed is deleted. + * Confirm validateTmpObject throws exception when requested to validate a bad checksum, + * and that the tmpFile passed is deleted. */ @Test public void validateTmpObject_validationRequested_nonMatchingChecksum() throws Exception { From 1aedf44955cbcd212f1ce91560def7ee285bffd7 Mon Sep 17 00:00:00 2001 From: Dou Mok Date: Wed, 13 Nov 2024 13:42:08 -0800 Subject: [PATCH 4/5] Add null check for 'validateTmpObject' method and new junit test --- .../hashstore/filehashstore/FileHashStore.java | 1 + .../filehashstore/FileHashStoreProtectedTest.java | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/org/dataone/hashstore/filehashstore/FileHashStore.java b/src/main/java/org/dataone/hashstore/filehashstore/FileHashStore.java index 65edeb45..5ec02dec 100644 --- a/src/main/java/org/dataone/hashstore/filehashstore/FileHashStore.java +++ b/src/main/java/org/dataone/hashstore/filehashstore/FileHashStore.java @@ -1258,6 +1258,7 @@ protected void validateTmpObject( } if (compareChecksum) { + FileHashStoreUtility.ensureNotNull(hexDigests, "hexDigests"); logFileHashStore.info("Validating object, checksum arguments supplied and valid."); String digestFromHexDigests = hexDigests.get(checksumAlgorithm); if (digestFromHexDigests == null) { diff --git a/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreProtectedTest.java b/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreProtectedTest.java index a36678b7..742b37a7 100644 --- a/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreProtectedTest.java +++ b/src/test/java/org/dataone/hashstore/filehashstore/FileHashStoreProtectedTest.java @@ -676,6 +676,18 @@ public void validateTmpObject_validationRequested_algoNotFound() throws Exceptio assertFalse(Files.exists(tmpFile.toPath())); } + /** + * Confirm validateTmpObject throws exception when hexDigests provided is null + */ + @Test + public void validateTmpObject_validationRequested_hexDigestsNull() throws Exception { + File tmpFile = generateTemporaryFile(); + + assertThrows(IllegalArgumentException.class, + () -> fileHashStore.validateTmpObject(true, "md2Digest", "MD2", tmpFile, null, + -1)); + } + /** * Check algorithm support for supported algorithm */ From ba90aa40f14bb0be998b3a6708cd2294ddb62b0e Mon Sep 17 00:00:00 2001 From: Dou Mok Date: Wed, 13 Nov 2024 13:55:46 -0800 Subject: [PATCH 5/5] Add null check for hexDigests in 'storeHardLink' method for 'FileHashStoreLinks' to be safe --- .../dataone/hashstore/hashstoreconverter/FileHashStoreLinks.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/dataone/hashstore/hashstoreconverter/FileHashStoreLinks.java b/src/main/java/org/dataone/hashstore/hashstoreconverter/FileHashStoreLinks.java index ff89c815..977245f0 100644 --- a/src/main/java/org/dataone/hashstore/hashstoreconverter/FileHashStoreLinks.java +++ b/src/main/java/org/dataone/hashstore/hashstoreconverter/FileHashStoreLinks.java @@ -94,6 +94,7 @@ public ObjectMetadata storeHardLink( try (InputStream fileStream = Files.newInputStream(filePath)) { Map hexDigests = generateChecksums(fileStream, checksumAlgorithm); + FileHashStoreUtility.ensureNotNull(hexDigests, "hexDigests"); String checksumToMatch = hexDigests.get(checksumAlgorithm); if (!checksum.equalsIgnoreCase(checksumToMatch)) { String errMsg = "Checksum supplied: " + checksum + " does not match what has been"