You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2024/01/19 07:05:29 UTC

(camel) branch typecoerce created (now 96ac8518d69)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a change to branch typecoerce
in repository https://gitbox.apache.org/repos/asf/camel.git


      at 96ac8518d69 CAMEL-20346: Comparison with type converters and stream caching should ensure the stream cache is reset so its re-readable afterwards. The contains function should also support file and stream cached input types

This branch includes the following new commits:

     new 96ac8518d69 CAMEL-20346: Comparison with type converters and stream caching should ensure the stream cache is reset so its re-readable afterwards. The contains function should also support file and stream cached input types

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(camel) 01/01: CAMEL-20346: Comparison with type converters and stream caching should ensure the stream cache is reset so its re-readable afterwards. The contains function should also support file and stream cached input types

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch typecoerce
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 96ac8518d69216304e466fcf4e92e0e0e0d00614
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Jan 19 08:05:15 2024 +0100

    CAMEL-20346: Comparison with type converters and stream caching should ensure the stream cache is reset so its re-readable afterwards. The contains function should also support file and stream cached input types
---
 .../camel/processor/StreamCachingChoiceTest.java   | 68 +++++++++++++++++++++
 .../StreamCachingChoiceWithVariableTest.java       | 69 ++++++++++++++++++++++
 .../camel/processor/ThrottlerMethodCallTest.java   |  2 +-
 .../org/apache/camel/util/ObjectHelperTest.java    | 50 ++++++++++++++++
 .../test/resources/org/apache/camel/util/foo.txt   |  1 +
 .../test/resources/org/apache/camel/util/quote.txt |  2 +
 .../org/apache/camel/support/ObjectHelper.java     | 57 ++++++++++++++----
 7 files changed, 237 insertions(+), 12 deletions(-)

diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/StreamCachingChoiceTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/StreamCachingChoiceTest.java
new file mode 100644
index 00000000000..a3ff48268dd
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/StreamCachingChoiceTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.processor;
+
+import java.io.File;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.converter.stream.FileInputStreamCache;
+import org.junit.jupiter.api.Test;
+
+public class StreamCachingChoiceTest extends ContextTestSupport {
+
+    private static final String TEST_FILE = "src/test/resources/org/apache/camel/converter/stream/test.xml";
+
+    @Test
+    public void testStreamCaching() throws Exception {
+        getMockEndpoint("mock:paris").expectedMessageCount(0);
+        getMockEndpoint("mock:madrid").expectedMessageCount(0);
+        getMockEndpoint("mock:london").expectedMessageCount(1);
+        getMockEndpoint("mock:other").expectedMessageCount(1);
+
+        File file = new File(TEST_FILE);
+        FileInputStreamCache cache = new FileInputStreamCache(file);
+        template.sendBody("direct:start", cache);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:start")
+                        .choice()
+                            .when().simple("${body} contains 'Paris'")
+                                .to("mock:paris")
+                            .when().simple("${body} contains 'London'")
+                                .to("mock:london")
+                            .otherwise()
+                                .to("mock:other")
+                        .end()
+                        .choice()
+                            .when().simple("${body} contains 'Paris'")
+                                .to("mock:paris")
+                            .when().simple("${body} contains 'Madrid'")
+                                .to("mock:madrid")
+                            .otherwise()
+                                .to("mock:other")
+                        .end();
+            }
+        };
+    }
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/StreamCachingChoiceWithVariableTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/StreamCachingChoiceWithVariableTest.java
new file mode 100644
index 00000000000..a24c1e6271c
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/StreamCachingChoiceWithVariableTest.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.processor;
+
+import java.io.File;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.converter.stream.FileInputStreamCache;
+import org.junit.jupiter.api.Test;
+
+public class StreamCachingChoiceWithVariableTest extends ContextTestSupport {
+
+    private static final String TEST_FILE = "src/test/resources/org/apache/camel/converter/stream/test.xml";
+
+    @Test
+    public void testStreamCaching() throws Exception {
+        getMockEndpoint("mock:paris").expectedMessageCount(0);
+        getMockEndpoint("mock:madrid").expectedMessageCount(0);
+        getMockEndpoint("mock:london").expectedMessageCount(1);
+        getMockEndpoint("mock:other").expectedMessageCount(1);
+
+        File file = new File(TEST_FILE);
+        FileInputStreamCache cache = new FileInputStreamCache(file);
+        template.sendBody("direct:start", cache);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:start")
+                        .setVariable("foo").simple("${body}")
+                        .choice()
+                            .when().simple("${variable:foo} contains 'Paris'")
+                                .to("mock:paris")
+                            .when().simple("${variable:foo} contains 'London'")
+                                .to("mock:london")
+                            .otherwise()
+                                .to("mock:other")
+                        .end()
+                        .choice()
+                            .when().simple("${variable:foo} contains 'Paris'")
+                                .to("mock:paris")
+                            .when().simple("${variable:foo} contains 'Madrid'")
+                                .to("mock:madrid")
+                            .otherwise()
+                                .to("mock:other")
+                        .end();
+            }
+        };
+    }
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/ThrottlerMethodCallTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/ThrottlerMethodCallTest.java
index 16f59048b60..14aa716a72f 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/ThrottlerMethodCallTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/ThrottlerMethodCallTest.java
@@ -70,7 +70,7 @@ public class ThrottlerMethodCallTest extends ContextTestSupport {
     }
 
     @Test
-    public void testConfigurationWithMethodCallExpression()  {
+    public void testConfigurationWithMethodCallExpression() {
         for (int i = 0; i < messageCount; i++) {
             executor.execute(() -> template.sendBody("direct:expressionMethod", "<message>payload</message>"));
         }
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java b/core/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
index e05d74e0ecf..b0fd15074a1 100644
--- a/core/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.util;
 
+import java.io.File;
 import java.io.InputStream;
 import java.lang.reflect.Method;
 import java.net.URL;
@@ -44,6 +45,7 @@ import org.apache.camel.component.bean.MyOtherFooBean.AbstractClassSize;
 import org.apache.camel.component.bean.MyOtherFooBean.Clazz;
 import org.apache.camel.component.bean.MyOtherFooBean.InterfaceSize;
 import org.apache.camel.component.bean.MyStaticClass;
+import org.apache.camel.converter.stream.FileInputStreamCache;
 import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.support.CamelContextHelper;
 import org.apache.camel.support.DefaultMessage;
@@ -124,6 +126,54 @@ public class ObjectHelperTest {
         }
     }
 
+    @Test
+    void testContainsStreamCaching() throws Exception {
+        try (CamelContext context = new DefaultCamelContext()) {
+            context.start();
+            TypeConverter tc = context.getTypeConverter();
+
+            File file = new File("src/test/resources/org/apache/camel/util/quote.txt");
+            FileInputStreamCache data = new FileInputStreamCache(file);
+
+            assertTrue(ObjectHelper.typeCoerceContains(tc, data, "foo", true));
+            assertTrue(ObjectHelper.typeCoerceContains(tc, data, "FOO", true));
+            assertFalse(ObjectHelper.typeCoerceContains(tc, data, "FOO", false));
+
+            assertTrue(ObjectHelper.typeCoerceContains(tc, data, "foo", true));
+            assertTrue(ObjectHelper.typeCoerceContains(tc, data, "FOO", true));
+            assertFalse(ObjectHelper.typeCoerceContains(tc, data, "FOO", false));
+
+            assertTrue(ObjectHelper.typeCoerceContains(tc, "foo", "foo", true));
+            assertFalse(ObjectHelper.typeCoerceContains(tc, data, "xyz", true));
+            assertFalse(ObjectHelper.typeCoerceContains(tc, data, "xyz", true));
+            assertFalse(ObjectHelper.typeCoerceContains(tc, "foo", "xyz", true));
+        }
+    }
+
+    @Test
+    void testEqualsStreamCaching() throws Exception {
+        try (CamelContext context = new DefaultCamelContext()) {
+            context.start();
+            TypeConverter tc = context.getTypeConverter();
+
+            File file = new File("src/test/resources/org/apache/camel/util/foo.txt");
+            FileInputStreamCache data = new FileInputStreamCache(file);
+
+            assertTrue(ObjectHelper.typeCoerceEquals(tc, data, "foo", true));
+            assertTrue(ObjectHelper.typeCoerceEquals(tc, data, "FOO", true));
+            assertFalse(ObjectHelper.typeCoerceEquals(tc, data, "FOO", false));
+
+            assertTrue(ObjectHelper.typeCoerceEquals(tc, data, "foo", true));
+            assertTrue(ObjectHelper.typeCoerceEquals(tc, data, "FOO", true));
+            assertFalse(ObjectHelper.typeCoerceEquals(tc, data, "FOO", false));
+
+            assertTrue(ObjectHelper.typeCoerceEquals(tc, "foo", "foo", true));
+            assertFalse(ObjectHelper.typeCoerceEquals(tc, data, "xyz", true));
+            assertFalse(ObjectHelper.typeCoerceEquals(tc, data, "xyz", true));
+            assertFalse(ObjectHelper.typeCoerceEquals(tc, "foo", "xyz", true));
+        }
+    }
+
     @Test
     void testContainsStringBuilder() throws Exception {
         try (CamelContext context = new DefaultCamelContext()) {
diff --git a/core/camel-core/src/test/resources/org/apache/camel/util/foo.txt b/core/camel-core/src/test/resources/org/apache/camel/util/foo.txt
new file mode 100644
index 00000000000..19102815663
--- /dev/null
+++ b/core/camel-core/src/test/resources/org/apache/camel/util/foo.txt
@@ -0,0 +1 @@
+foo
\ No newline at end of file
diff --git a/core/camel-core/src/test/resources/org/apache/camel/util/quote.txt b/core/camel-core/src/test/resources/org/apache/camel/util/quote.txt
new file mode 100644
index 00000000000..06564a61da9
--- /dev/null
+++ b/core/camel-core/src/test/resources/org/apache/camel/util/quote.txt
@@ -0,0 +1,2 @@
+Hello foo how are you?
+Thank you I am going to the bar now.
\ No newline at end of file
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ObjectHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/ObjectHelper.java
index c1876c76482..3c0d30cb902 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ObjectHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ObjectHelper.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.support;
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.lang.reflect.Array;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -45,7 +47,9 @@ import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.Ordered;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.StreamCache;
 import org.apache.camel.TypeConverter;
+import org.apache.camel.WrappedFile;
 import org.apache.camel.util.ReflectionHelper;
 import org.apache.camel.util.Scanner;
 import org.apache.camel.util.StringHelper;
@@ -145,15 +149,28 @@ public final class ObjectHelper {
         }
 
         // convert left to right
-        Object value = converter.tryConvertTo(rightValue.getClass(), leftValue);
-        final boolean isEqualLeftToRight = org.apache.camel.util.ObjectHelper.equal(value, rightValue, ignoreCase);
-        if (isEqualLeftToRight) {
-            return true;
-        }
+        StreamCache sc = null;
+        try {
+            if (leftValue instanceof StreamCache) {
+                sc = (StreamCache) leftValue;
+            }
+            Object value = converter.tryConvertTo(rightValue.getClass(), leftValue);
+            final boolean isEqualLeftToRight = org.apache.camel.util.ObjectHelper.equal(value, rightValue, ignoreCase);
+            if (isEqualLeftToRight) {
+                return true;
+            }
 
-        // convert right to left
-        value = converter.tryConvertTo(leftValue.getClass(), rightValue);
-        return org.apache.camel.util.ObjectHelper.equal(leftValue, value, ignoreCase);
+            // convert right to left
+            if (rightValue instanceof StreamCache) {
+                sc = (StreamCache) rightValue;
+            }
+            value = converter.tryConvertTo(leftValue.getClass(), rightValue);
+            return org.apache.camel.util.ObjectHelper.equal(leftValue, value, ignoreCase);
+        } finally {
+            if (sc != null) {
+                sc.reset();
+            }
+        }
     }
 
     private static boolean booleanStringComparison(Boolean leftBool, String rightValue) {
@@ -964,14 +981,32 @@ public final class ObjectHelper {
      */
     public static boolean typeCoerceContains(
             TypeConverter typeConverter, Object collectionOrArray, Object value, boolean ignoreCase) {
+
+        // unwrap file
+        if (collectionOrArray instanceof WrappedFile<?> wf) {
+            collectionOrArray = wf.getBody();
+        }
+        if (collectionOrArray instanceof StreamCache sc) {
+            try {
+                ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                sc.writeTo(bos);
+                collectionOrArray = bos.toByteArray();
+            } catch (IOException e) {
+                // ignore
+            } finally {
+                sc.reset();
+            }
+        }
         // favor String types
+        if (value instanceof StringBuffer || value instanceof StringBuilder) {
+            value = value.toString();
+        }
         if (collectionOrArray instanceof StringBuffer || collectionOrArray instanceof StringBuilder) {
             collectionOrArray = collectionOrArray.toString();
         }
-        if (value instanceof StringBuffer || value instanceof StringBuilder) {
-            value = value.toString();
+        if (collectionOrArray instanceof byte[] arr) {
+            collectionOrArray = new String(arr);
         }
-
         if (collectionOrArray instanceof Collection) {
             Collection<?> collection = (Collection<?>) collectionOrArray;
             if (ignoreCase) {