From 6a1e23c574e15b6bdb086872b4afbe4fd6699a84 Mon Sep 17 00:00:00 2001 From: Jason Wells Date: Tue, 24 Mar 2020 10:20:19 -0700 Subject: [PATCH] Update ProfileDigester.java - Reuse of MessageDigester - Synchronize generateMd5Byte method since digester is reused and MetadataItem objects of MetadataProfile may behave oddly when evaluate method called concurrently --- .../superutilities/misc/ProfileDigester.java | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/Java/src/main/java/com/nuix/superutilities/misc/ProfileDigester.java b/Java/src/main/java/com/nuix/superutilities/misc/ProfileDigester.java index a31bf71..6dc85c8 100644 --- a/Java/src/main/java/com/nuix/superutilities/misc/ProfileDigester.java +++ b/Java/src/main/java/com/nuix/superutilities/misc/ProfileDigester.java @@ -2,6 +2,7 @@ import java.nio.charset.Charset; import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -29,6 +30,8 @@ public class ProfileDigester { private Consumer infoMessageCallback = null; private BiConsumer errorCallback = null; + private MessageDigest md5Digester = null; + private void fireProgressUpdate(int current, int total) { if(progressCallback != null) { progressCallback.accept(current, total); @@ -76,8 +79,17 @@ public void whenErrorLogged(BiConsumer callback) { errorCallback = callback; } - public ProfileDigester() {} - public ProfileDigester(MetadataProfile metadataProfile) { profile = metadataProfile; } + public ProfileDigester() { + try { + md5Digester = MessageDigest.getInstance("md5"); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + } + public ProfileDigester(MetadataProfile metadataProfile) { + this(); + profile = metadataProfile; + } /*** * Adds items to an item set using "Scripted" deduplication, providing a MD5 hash generated from the concatenation of the values yielded @@ -126,7 +138,7 @@ public ItemSet addItemsToItemSet(Case nuixCase, String itemSetName, String dedup if(includeItemText) { description = String.format("Generated using MD5 of profile '%s' field values concatenation and Item Text", profile.getName()); } else { - description = String.format("Generated using MD5 of profile '%s' field values concatenationt", profile.getName()); + description = String.format("Generated using MD5 of profile '%s' field values concatenation", profile.getName()); } Map itemSetSettings = new HashMap(); @@ -175,28 +187,34 @@ public void itemProcessed(ItemEventInfo info) { /*** * Generates MD5 digest byte array for a given item. Digest is generated by digesting concatenation of values yielded by the * metadata profile associated with this instance for the given item and optionally including the item's content text. + * Note that method is synchronized due to: + * - Reuse of MD5 digester + * - Some metadata profile fields don't seem to play nice when called concurrently * @param item The item to generate a custom MD5 digest for. * @return Byte array representation of the MD5 digest * @throws Exception Most likely if metadata profile has not yet been set for this instance. */ - public byte[] generateMd5Bytes(Item item) throws Exception { + public synchronized byte[] generateMd5Bytes(Item item) throws Exception { if(profile == null) { throw new IllegalArgumentException("profile cannot be null, please provide a profile by calling setProfile(MetadataProfile profile) before calling this method"); } - MessageDigest md = MessageDigest.getInstance("MD5"); for(MetadataItem field : profile.getMetadata()) { String fieldValue = field.evaluate(item); if(fieldValue != null) { - md.update(fieldValue.getBytes()); + md5Digester.update(fieldValue.getBytes()); } } if(includeItemText) { - md.update(item.getTextObject().toString().getBytes(Charset.forName("utf8"))); + md5Digester.update(item.getTextObject().toString().getBytes(Charset.forName("utf8"))); } - return md.digest(); + // Capture our result and then cleanup for the next call + byte[] result = md5Digester.digest(); + md5Digester.reset(); + + return result; } /***