This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch hash in repository https://gitbox.apache.org/repos/asf/camel.git
commit f00699e9d831567ae015e364ef8810e9ec03b2f3 Author: Claus Ibsen <[email protected]> AuthorDate: Tue Jan 13 11:26:09 2026 +0100 CAMEL-22847: camel-core - Optimize simple hash function to calc hash with low memory --- .../language/simple/SimpleExpressionBuilder.java | 16 ++++++++++++---- .../apache/camel/language/simple/SimpleTest.java | 22 ++++++++++++++++++++++ .../main/java/org/apache/camel/util/IOHelper.java | 4 ++-- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java index 02f807b828f9..1d812915dda4 100644 --- a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java +++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java @@ -16,6 +16,7 @@ */ package org.apache.camel.language.simple; +import java.io.InputStream; import java.security.MessageDigest; import java.util.ArrayList; import java.util.Arrays; @@ -559,14 +560,21 @@ public final class SimpleExpressionBuilder { @Override public Object evaluate(Exchange exchange) { - byte[] data = exp.evaluate(exchange, byte[].class); - if (data != null && data.length > 0) { + InputStream is = exp.evaluate(exchange, InputStream.class); + if (is != null) { try { + // calculate the hash in chunks in case the payload is big MessageDigest digest = MessageDigest.getInstance(algorithm); - byte[] bytes = digest.digest(data); - return StringHelper.bytesToHex(bytes); + byte[] buffer = new byte[1024]; + for (int n = is.read(buffer, 0, 1024); n > -1; n = is.read(buffer, 0, 1024)) { + digest.update(buffer, 0, n); + } + return StringHelper.bytesToHex(digest.digest()); } catch (Exception e) { throw CamelExecutionException.wrapCamelExecutionException(exchange, e); + } finally { + // reset cached streams so they can be read again + MessageHelper.resetStreamCache(exchange.getMessage()); } } return null; diff --git a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java index ecb88e21b8fa..553f38e64241 100644 --- a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java @@ -16,6 +16,7 @@ */ package org.apache.camel.language.simple; +import java.io.File; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.util.ArrayList; @@ -37,7 +38,9 @@ import org.apache.camel.ExpressionIllegalSyntaxException; import org.apache.camel.InvalidPayloadException; import org.apache.camel.LanguageTestSupport; import org.apache.camel.Predicate; +import org.apache.camel.StreamCache; import org.apache.camel.component.bean.MethodNotFoundException; +import org.apache.camel.converter.stream.FileInputStreamCache; import org.apache.camel.language.bean.RuntimeBeanExpressionException; import org.apache.camel.language.simple.myconverter.MyCustomDate; import org.apache.camel.language.simple.types.SimpleIllegalSyntaxException; @@ -2397,6 +2400,25 @@ public class SimpleTest extends LanguageTestSupport { assertNull(s); } + @Test + public void testHashStreamCache() throws Exception { + File f = new File("src/test/resources/log4j2.properties"); + StreamCache sc = new FileInputStreamCache(f); + assertEquals(-1, sc.position()); + exchange.getMessage().setBody(sc); + Expression expression = context.resolveLanguage("simple").createExpression("${hash(${body})}"); + String s = expression.evaluate(exchange, String.class); + assertNotNull(s); + // should reset so we can read it again + assertEquals(-1, sc.position()); + + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] arr = context.getTypeConverter().convertTo(byte[].class, f); + byte[] bytes = digest.digest(arr); + String expected = StringHelper.bytesToHex(bytes); + assertEquals(expected, s); + } + @Test public void testTrim() { exchange.getMessage().setBody(" Hello World "); diff --git a/core/camel-util/src/main/java/org/apache/camel/util/IOHelper.java b/core/camel-util/src/main/java/org/apache/camel/util/IOHelper.java index 58e2f74a3396..e5f74deed6cb 100644 --- a/core/camel-util/src/main/java/org/apache/camel/util/IOHelper.java +++ b/core/camel-util/src/main/java/org/apache/camel/util/IOHelper.java @@ -274,7 +274,7 @@ public final class IOHelper { * * @param input the input stream buffer * @param output the output stream buffer - * @throws IOException + * @throws IOException for I/O errors */ public static void copyAndCloseInput(InputStream input, OutputStream output) throws IOException { copy(input, output); @@ -289,7 +289,7 @@ public final class IOHelper { * @param input the input stream buffer * @param output the output stream buffer * @param bufferSize the size of the buffer used for the copies - * @throws IOException + * @throws IOException for I/O errors */ public static void copyAndCloseInput(InputStream input, OutputStream output, int bufferSize) throws IOException { copy(input, output, bufferSize);
