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);

Reply via email to