You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2019/06/06 07:15:39 UTC

[camel] branch camel-2.24.x updated (26464c1 -> a3794d1)

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

acosentino pushed a change to branch camel-2.24.x
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from 26464c1  [CAMEL-13593]ensure javax.mail dependency still in camel-mail.pom
     new 1aab75f  CAMEL-13316: Olingo components handle value/property results
     new 27e9e6d  CAMEL-13316: Fixed CS for Olingo 2
     new a3794d1  fix(13606): Stop Olingo Index Classes generating NP Exceptions

The 3 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.


Summary of changes:
 .../camel/component/olingo2/Olingo2Consumer.java   |   4 +-
 .../camel/component/olingo2/Olingo2Index.java      |  71 ++++++-
 .../olingo2/Olingo2ComponentConsumerTest.java      | 234 +++++++++++++++++++++
 ...Test.java => Olingo2ComponentProducerTest.java} | 106 +---------
 .../camel/component/olingo4/Olingo4Consumer.java   |   9 +-
 .../camel/component/olingo4/Olingo4Index.java      |  23 +-
 .../olingo4/Olingo4ComponentConsumerTest.java      | 211 +++++++++++++++++++
 ...Test.java => Olingo4ComponentProducerTest.java} | 105 +--------
 8 files changed, 555 insertions(+), 208 deletions(-)
 create mode 100644 components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentConsumerTest.java
 rename components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/{Olingo2ComponentTest.java => Olingo2ComponentProducerTest.java} (79%)
 create mode 100644 components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentConsumerTest.java
 rename components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/{Olingo4ComponentTest.java => Olingo4ComponentProducerTest.java} (82%)


[camel] 03/03: fix(13606): Stop Olingo Index Classes generating NP Exceptions

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

acosentino pushed a commit to branch camel-2.24.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit a3794d195aa7bb707f404fbcd4005429eaf73f54
Author: phantomjinx <p....@phantomjinx.co.uk>
AuthorDate: Wed Jun 5 11:04:07 2019 +0100

    fix(13606): Stop Olingo Index Classes generating NP Exceptions
    
    * Olingo*Index
     * Provides null-checks to each method to avoid any NPE
    
    * Tests
     * The consumer testing routes were being started prior to the tests that
       concerned them. Consequently, it was hit/miss whether the tests would
       catch all messages generated by the routes. This matters for the
       'already seen' tests as adding more of there meant tests failed with
       messages having no bodies.
     * Consumer tests broken out into their own classes and camel context
       started in the test once the mock endpoints have been property setup.
---
 .../camel/component/olingo2/Olingo2Index.java      |  71 ++++++-
 .../olingo2/Olingo2ComponentConsumerTest.java      | 234 +++++++++++++++++++++
 ...Test.java => Olingo2ComponentProducerTest.java} | 148 +------------
 .../camel/component/olingo4/Olingo4Index.java      |  23 +-
 .../olingo4/Olingo4ComponentConsumerTest.java      | 211 +++++++++++++++++++
 ...Test.java => Olingo4ComponentProducerTest.java} | 134 +-----------
 6 files changed, 546 insertions(+), 275 deletions(-)

diff --git a/components/camel-olingo2/camel-olingo2-component/src/main/java/org/apache/camel/component/olingo2/Olingo2Index.java b/components/camel-olingo2/camel-olingo2-component/src/main/java/org/apache/camel/component/olingo2/Olingo2Index.java
index 1198a10..c6a0f2a 100644
--- a/components/camel-olingo2/camel-olingo2-component/src/main/java/org/apache/camel/component/olingo2/Olingo2Index.java
+++ b/components/camel-olingo2/camel-olingo2-component/src/main/java/org/apache/camel/component/olingo2/Olingo2Index.java
@@ -18,17 +18,47 @@ package org.apache.camel.component.olingo2;
 
 import java.lang.reflect.Array;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import org.apache.olingo.odata2.api.ep.entry.EntryMetadata;
 import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.FeedMetadata;
 import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
 
 public class Olingo2Index {
 
     private Set<Integer> resultIndex = new HashSet<>();
 
+    private class EmptyODataFeed implements ODataFeed {
+
+        @Override
+        public List<ODataEntry> getEntries() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public FeedMetadata getFeedMetadata() {
+            return new FeedMetadata() {
+                @Override
+                public String getDeltaLink() {
+                    return null;
+                }
+
+                @Override
+                public Integer getInlineCount() {
+                    return 0;
+                }
+
+                @Override
+                public String getNextLink() {
+                    return null;
+                }
+            };
+        }
+    }
+
     /**
      * Hash only certain data since other parts change between message
      * exchanges.
@@ -64,18 +94,41 @@ public class Olingo2Index {
     }
 
     private Object filter(Object o) {
-        if (resultIndex.contains(o.hashCode())) {
+        if (o == null || resultIndex.contains(o.hashCode())) {
             return null;
         }
         return o;
     }
 
     private void indexDefault(Object o) {
+        if (o == null) {
+            return;
+        }
+
         resultIndex.add(o.hashCode());
     }
 
+    private Object filter(ODataEntry entry) {
+        if (entry == null || resultIndex.contains(hash(entry))) {
+            return null;
+        }
+        return entry;
+    }
+
+    private void index(ODataEntry entry) {
+        if (entry == null) {
+            return;
+        }
+
+        resultIndex.add(hash(entry));
+    }
+
     private Iterable<?> filter(Iterable<?> iterable) {
         List<Object> filtered = new ArrayList<>();
+        if (iterable == null) {
+            return filtered;
+        }
+
         for (Object o : iterable) {
             if (resultIndex.contains(o.hashCode())) {
                 continue;
@@ -87,12 +140,20 @@ public class Olingo2Index {
     }
 
     private void index(Iterable<?> iterable) {
+        if (iterable == null) {
+            return;
+        }
+
         for (Object o : iterable) {
             resultIndex.add(o.hashCode());
         }
     }
 
     private ODataFeed filter(ODataFeed odataFeed) {
+        if (odataFeed == null) {
+            return new EmptyODataFeed();
+        }
+
         List<ODataEntry> entries = odataFeed.getEntries();
 
         if (entries.isEmpty()) {
@@ -111,6 +172,10 @@ public class Olingo2Index {
     }
 
     private void index(ODataFeed odataFeed) {
+        if (odataFeed == null) {
+            return;
+        }
+
         for (ODataEntry entry : odataFeed.getEntries()) {
             resultIndex.add(hash(entry));
         }
@@ -124,6 +189,8 @@ public class Olingo2Index {
             index((ODataFeed) result);
         } else if (result instanceof Iterable) {
             index((Iterable<?>) result);
+        } else if (result instanceof ODataEntry) {
+            index((ODataEntry) result);
         } else {
             indexDefault(result);
         }
@@ -142,6 +209,8 @@ public class Olingo2Index {
                 result.add(Array.get(response, i));
             }
             response = filter(result);
+        } else if (response instanceof ODataEntry) {
+            response = filter((ODataEntry) response);
         } else {
             response = filter(response);
         }
diff --git a/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentConsumerTest.java b/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentConsumerTest.java
new file mode 100644
index 0000000..e95c53e
--- /dev/null
+++ b/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentConsumerTest.java
@@ -0,0 +1,234 @@
+/**
+ * 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.component.olingo2;
+
+import java.util.Map;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.AvailablePortFinder;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test class for {@link org.apache.camel.component.olingo2.api.Olingo2App} APIs.
+ * <p>
+ * The integration test runs against Apache Olingo 2.0 sample server
+ * which is dynamically installed and started during the test.
+ * </p>
+ */
+public class Olingo2ComponentConsumerTest extends AbstractOlingo2TestSupport {
+
+    private static final int PORT = AvailablePortFinder.getNextAvailable();
+    private static final String TEST_SERVICE_URL = "http://localhost:" + PORT + "/MyFormula.svc";
+
+    private static Olingo2SampleServer server;
+
+    public Olingo2ComponentConsumerTest() {
+        setDefaultTestProperty("serviceUri", "http://localhost:" + PORT + "/MyFormula.svc");
+    }
+
+    @BeforeClass
+    public static void beforeClass() throws Exception {
+        startServers(PORT);
+        Olingo2SampleServer.generateSampleData(TEST_SERVICE_URL);
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception {
+        if (server != null) {
+            server.stop();
+            server.destroy();
+        }
+    }
+
+    protected static void startServers(int port) throws Exception {
+        server = new Olingo2SampleServer(port, "/olingo2_ref");
+        server.start();
+    }
+
+    private void addRouteAndStartContext(RouteBuilder builder) throws Exception {
+        context().addRoutes(builder);
+        startCamelContext();
+    }
+
+    /**
+     * Read entity set of the People object
+     * and filter already seen items on subsequent exchanges
+     * Use a delay since the mock endpoint does not always get
+     * the correct number of exchanges before being satisfied.
+     *
+     * Note:
+     * - consumer.splitResults is set to false since this ensures the first returned message
+     *   contains all the results. This is preferred for the purposes of this test. The default
+     *   will mean the first n messages contain the results (where n is the result total) then
+     *   subsequent messages will be empty
+     */
+    @Test
+    public void testConsumerReadFilterAlreadySeen() throws Exception {
+        int expectedMsgCount = 3;
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-alreadyseen");
+        mockEndpoint.expectedMessageCount(expectedMsgCount);
+        mockEndpoint.setResultWaitTime(60000);
+
+        RouteBuilder builder = new RouteBuilder() {
+            public void configure() {
+                from("olingo2://read/Manufacturers?filterAlreadySeen=true&"
+                        + "consumer.delay=2&consumer.sendEmptyMessageWhenIdle=true&"
+                        + "consumer.splitResult=false")
+                    .to("mock:consumer-alreadyseen");
+            };
+        };
+        addRouteAndStartContext(builder);
+
+        mockEndpoint.assertIsSatisfied();
+
+        for (int i = 0; i < expectedMsgCount; ++i) {
+            Object body = mockEndpoint.getExchanges().get(i).getIn().getBody();
+
+            if (i == 0) {
+                //
+                // First polled messages contained all the manufacturers
+                //
+                assertTrue(body instanceof ODataFeed);
+                ODataFeed set = (ODataFeed) body;
+                assertTrue(set.getEntries().size() > 0);
+            } else {
+                //
+                // Subsequent polling messages should be empty
+                // since the filterAlreadySeen property is true
+                //
+                assertNull(body);
+            }
+        }
+    }
+
+    @Test
+    public void testConsumerReadFilterAlreadySeenWithPredicateAndSplitResults() throws Exception {
+        int expectedMsgCount = 3;
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-splitresult-kp-manufacturer");
+        mockEndpoint.expectedMinimumMessageCount(expectedMsgCount);
+
+        RouteBuilder builder = new RouteBuilder() {
+            public void configure() {
+                from("olingo2://read/Manufacturers('1')?filterAlreadySeen=true&"
+                        + "consumer.delay=2&consumer.sendEmptyMessageWhenIdle=true&"
+                        + "consumer.splitResult=true")
+                    .to("mock:consumer-splitresult-kp-manufacturer");
+            };
+        };
+        addRouteAndStartContext(builder);
+
+        mockEndpoint.assertIsSatisfied();
+
+        for (int i = 0; i < expectedMsgCount; ++i) {
+            Object body = mockEndpoint.getExchanges().get(i).getIn().getBody();
+
+            if (i == 0) {
+                //
+                // First polled messages contained all the entities
+                //
+                assertTrue(body instanceof ODataEntry);
+                ODataEntry entry = (ODataEntry) body;
+                Object nameValue = entry.getProperties().get("Name");
+                assertNotNull(nameValue);
+                assertEquals("Star Powered Racing", nameValue.toString());
+            } else {
+                //
+                // Subsequent polling messages should be empty
+                // since the filterAlreadySeen property is true
+                //
+                assertNull(body);
+            }
+        }
+    }
+
+    /**
+     * Read value of the People object and split the results
+     * into individual messages
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testConsumerReadClientValuesSplitResults() throws Exception {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-value");
+        mockEndpoint.expectedMinimumMessageCount(1);
+        mockEndpoint.setResultWaitTime(60000);
+
+        RouteBuilder builder = new RouteBuilder() {
+            public void configure() {
+                from("olingo2://read/Manufacturers('1')/Address?consumer.splitResult=true")
+                    .to("mock:consumer-value");
+            };
+        };
+        addRouteAndStartContext(builder);
+
+        mockEndpoint.assertIsSatisfied();
+        //
+        // 1 individual message in the exchange
+        //
+        Object body = mockEndpoint.getExchanges().get(0).getIn().getBody();
+        assertIsInstanceOf(Map.class, body);
+        Map<String, Object> value = (Map<String, Object>) body;
+        Object addrObj = value.get("Address");
+        assertIsInstanceOf(Map.class, addrObj);
+        Map<String, Object> addrMap = (Map<String, Object>) addrObj;
+        assertEquals("70173", addrMap.get("ZipCode"));
+        assertEquals("Star Street 137", addrMap.get("Street"));
+        assertEquals("Germany", addrMap.get("Country"));
+        assertEquals("Stuttgart", addrMap.get("City"));
+    }
+
+    /**
+     * Read entity set of the Manufacturers object and split the results
+     * into individual messages
+     */
+    @Test
+    public void testConsumerReadSplitResults() throws Exception {
+        int expectedMsgCount = 2;
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-splitresult");
+        mockEndpoint.expectedMinimumMessageCount(expectedMsgCount);
+
+        RouteBuilder builder = new RouteBuilder() {
+            public void configure() {
+                from("olingo2://read/Manufacturers?consumer.splitResult=true")
+                    .to("mock:consumer-splitresult");
+            };
+        };
+
+        addRouteAndStartContext(builder);
+
+        mockEndpoint.assertIsSatisfied();
+
+        //
+        // 2 individual messages in the exchange,
+        // each containing a different entity.
+        //
+        for (int i = 0; i < expectedMsgCount; ++i) {
+            Object body = mockEndpoint.getExchanges().get(i).getIn().getBody();
+            assertTrue(body instanceof ODataEntry);
+            ODataEntry entry = (ODataEntry)body;
+            Map<String, Object> properties = entry.getProperties();
+            assertNotNull(properties);
+
+            Object name = properties.get("Name");
+            assertNotNull(name);
+            assertTrue(name.toString().contains("Powered Racing"));
+        }
+    }
+}
diff --git a/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentTest.java b/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentProducerTest.java
similarity index 73%
rename from components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentTest.java
rename to components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentProducerTest.java
index e544b79..589f2fd 100644
--- a/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentTest.java
+++ b/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentProducerTest.java
@@ -49,10 +49,10 @@ import org.slf4j.LoggerFactory;
  * which is dynamically installed and started during the test.
  * </p>
  */
-public class Olingo2ComponentTest extends AbstractOlingo2TestSupport {
+public class Olingo2ComponentProducerTest extends AbstractOlingo2TestSupport {
 
-    private static final Logger LOG = LoggerFactory.getLogger(Olingo2ComponentTest.class);
-    private static final int PORT = AvailablePortFinder.getNextAvailable();  
+    private static final Logger LOG = LoggerFactory.getLogger(Olingo2ComponentProducerTest.class);
+    private static final int PORT = AvailablePortFinder.getNextAvailable();
     private static final String ID_PROPERTY = "Id";
     private static final String MANUFACTURERS = "Manufacturers";
     private static final String TEST_MANUFACTURER = "Manufacturers('1')";
@@ -66,7 +66,7 @@ public class Olingo2ComponentTest extends AbstractOlingo2TestSupport {
 
     private static Olingo2SampleServer server;
 
-    public Olingo2ComponentTest() {
+    public Olingo2ComponentProducerTest() {
         setDefaultTestProperty("serviceUri", "http://localhost:" + PORT + "/MyFormula.svc");
     }
 
@@ -248,89 +248,10 @@ public class Olingo2ComponentTest extends AbstractOlingo2TestSupport {
     }
 
     /**
-     * Read entity set of the People object
-     * and filter already seen items on subsequent exchanges
-     * Use a delay since the mock endpoint does not always get
-     * the correct number of exchanges before being satisfied.
      *
-     * Note:
-     * - consumer.splitResults is set to false since this ensures the first returned message
-     *   contains all the results. This is preferred for the purposes of this test. The default
-     *   will mean the first n messages contain the results (where n is the result total) then
-     *   subsequent messages will be empty
-     */
-    @Test
-    public void testConsumerReadFilterAlreadySeen() throws Exception {
-        final Map<String, Object> headers = new HashMap<>();
-        String endpoint = "olingo2://read/Manufacturers?filterAlreadySeen=true&consumer.delay=2&consumer.sendEmptyMessageWhenIdle=true&consumer.splitResult=false";
-
-        int expectedMsgCount = 3;
-        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-alreadyseen");
-        mockEndpoint.expectedMessageCount(expectedMsgCount);
-        mockEndpoint.setResultWaitTime(60000);
-
-        final ODataFeed manufacturers = (ODataFeed)requestBodyAndHeaders(endpoint, null, headers);
-        assertNotNull(manufacturers);
-        int expectedManufacturers = manufacturers.getEntries().size();
-
-        mockEndpoint.assertIsSatisfied();
-
-        for (int i = 0; i < expectedMsgCount; ++i) {
-            Object body = mockEndpoint.getExchanges().get(i).getIn().getBody();
-
-            if (i == 0) {
-                //
-                // First polled messages contained all the manufacturers
-                //
-                assertTrue(body instanceof ODataFeed);
-                ODataFeed set = (ODataFeed) body;
-                assertEquals(expectedManufacturers, set.getEntries().size());
-            } else {
-                //
-                // Subsequent polling messages should be empty
-                // since the filterAlreadySeen property is true
-                //
-                assertNull(body);
-            }
-        }
-    }
-
-    /**
-     * Read value of the People object and split the results
-     * into individual messages
-     */
-    @Test
-    public void testConsumerReadClientValuesSplitResults() throws Exception {
-        final Map<String, Object> headers = new HashMap<>();
-        String endpoint = "olingo2://read/Manufacturers('1')/Address?consumer.splitResult=true";
-
-        this.context.setTracing(true);
-        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-value");
-        mockEndpoint.expectedMinimumMessageCount(1);
-        mockEndpoint.setResultWaitTime(60000);
-
-        final Map<String, Object> resultValue = requestBodyAndHeaders(endpoint, null, headers);
-        assertNotNull(resultValue);
-
-        mockEndpoint.assertIsSatisfied();
-        //
-        // 1 individual message in the exchange
-        //
-        Object body = mockEndpoint.getExchanges().get(0).getIn().getBody();
-        assertIsInstanceOf(Map.class, body);
-        Map<String, Object> value = (Map<String, Object>) body;
-        Object addrObj = value.get("Address");
-        assertIsInstanceOf(Map.class, addrObj);
-        Map<String, Object> addrMap = (Map<String, Object>) addrObj;
-        assertEquals("70173", addrMap.get("ZipCode"));
-        assertEquals("Star Street 137", addrMap.get("Street"));
-        assertEquals("Germany", addrMap.get("Country"));
-        assertEquals("Stuttgart", addrMap.get("City"));
-    }
-
-    /**
-     * Read entity set of the People object and with no filter already seen, all
-     * items should be present in each message
+     * Read entity set of the People object
+     * and with no filter already seen, all items
+     * should be present in each message
      *
      * @throws Exception
      */
@@ -410,49 +331,6 @@ public class Olingo2ComponentTest extends AbstractOlingo2TestSupport {
         }
     }
 
-    /**
-     * Read entity set of the Manufacturers object and split the results
-     * into individual messages
-     */
-    @Test
-    public void testConsumerReadSplitResults() throws Exception {
-        final Map<String, Object> headers = new HashMap<>();
-        String endpoint = "olingo2://read/Manufacturers?consumer.splitResult=true";
-
-        int expectedMsgCount = 2;
-        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-splitresult");
-        mockEndpoint.expectedMessageCount(expectedMsgCount);
-
-        final ODataFeed odataFeed = (ODataFeed)requestBodyAndHeaders(endpoint, null, headers);
-        assertNotNull(odataFeed);
-
-        mockEndpoint.assertIsSatisfied();
-
-        //
-        // 2 individual messages in the exchange,
-        // each containing a different entity.
-        //
-        for (int i = 0; i < expectedMsgCount; ++i) {
-            Object body = mockEndpoint.getExchanges().get(i).getIn().getBody();
-            assertTrue(body instanceof ODataEntry);
-            ODataEntry entry = (ODataEntry)body;
-            Map<String, Object> properties = entry.getProperties();
-            assertNotNull(properties);
-
-            Object name = properties.get("Name");
-            assertNotNull(name);
-            switch(i) {
-            case 0:
-                assertEquals("Star Powered Racing", name);
-                break;
-            case 1:
-                assertEquals("Horse Powered Racing", name);
-                break;
-            default:
-            }
-        }
-    }
-
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
@@ -500,18 +378,6 @@ public class Olingo2ComponentTest extends AbstractOlingo2TestSupport {
                 from("direct:read-people-filterseen")
                     .to("olingo2://read/Manufacturers?filterAlreadySeen=true")
                     .to("mock:producer-alreadyseen");
-
-                //
-                // Consumer endpoint
-                //
-                from("olingo2://read/Manufacturers?filterAlreadySeen=true&consumer.delay=2&consumer.sendEmptyMessageWhenIdle=true&consumer.splitResult=false")
-                    .to("mock:consumer-alreadyseen");
-
-                from("olingo2://read/Manufacturers?consumer.splitResult=true")
-                    .to("mock:consumer-splitresult");
-
-                from("olingo2://read/Manufacturers('1')/Address?consumer.splitResult=true")
-                    .to("mock:consumer-value");
             }
         };
     }
diff --git a/components/camel-olingo4/camel-olingo4-component/src/main/java/org/apache/camel/component/olingo4/Olingo4Index.java b/components/camel-olingo4/camel-olingo4-component/src/main/java/org/apache/camel/component/olingo4/Olingo4Index.java
index c00adbb..d4db500 100644
--- a/components/camel-olingo4/camel-olingo4-component/src/main/java/org/apache/camel/component/olingo4/Olingo4Index.java
+++ b/components/camel-olingo4/camel-olingo4-component/src/main/java/org/apache/camel/component/olingo4/Olingo4Index.java
@@ -23,24 +23,33 @@ import java.util.List;
 import java.util.Set;
 import org.apache.olingo.client.api.domain.ClientEntity;
 import org.apache.olingo.client.api.domain.ClientEntitySet;
+import org.apache.olingo.client.core.domain.ClientEntitySetImpl;
 
 public class Olingo4Index {
 
     private Set<Integer> resultIndex = new HashSet<>();
 
     private Object filter(Object o) {
-        if (resultIndex.contains(o.hashCode())) {
+        if (o == null || resultIndex.contains(o.hashCode())) {
             return null;
         }
         return o;
     }
 
     private void indexDefault(Object o) {
+        if (o == null) {
+            return;
+        }
+
         resultIndex.add(o.hashCode());
     }
 
     private Iterable<?> filter(Iterable<?> iterable) {
         List<Object> filtered = new ArrayList<>();
+        if (iterable == null) {
+            return filtered;
+        }
+
         for (Object o : iterable) {
             if (resultIndex.contains(o.hashCode())) {
                 continue;
@@ -52,12 +61,20 @@ public class Olingo4Index {
     }
 
     private void index(Iterable<?> iterable) {
+        if (iterable == null) {
+            return;
+        }
+
         for (Object o : iterable) {
             resultIndex.add(o.hashCode());
         }
     }
 
     private ClientEntitySet filter(ClientEntitySet entitySet) {
+        if (entitySet == null) {
+            return new ClientEntitySetImpl();
+        }
+
         List<ClientEntity> entities = entitySet.getEntities();
 
         if (entities.isEmpty()) {
@@ -77,6 +94,10 @@ public class Olingo4Index {
     }
 
     private void index(ClientEntitySet entitySet) {
+        if (entitySet == null) {
+            return;
+        }
+
         for (ClientEntity entity : entitySet.getEntities()) {
             resultIndex.add(entity.hashCode());
         }
diff --git a/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentConsumerTest.java b/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentConsumerTest.java
new file mode 100644
index 0000000..ebf1b0f
--- /dev/null
+++ b/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentConsumerTest.java
@@ -0,0 +1,211 @@
+/**
+ * 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.component.olingo4;
+
+import java.util.Iterator;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.olingo.client.api.domain.ClientCollectionValue;
+import org.apache.olingo.client.api.domain.ClientComplexValue;
+import org.apache.olingo.client.api.domain.ClientEntity;
+import org.apache.olingo.client.api.domain.ClientEntitySet;
+import org.apache.olingo.client.api.domain.ClientPrimitiveValue;
+import org.apache.olingo.client.api.domain.ClientProperty;
+import org.junit.Test;
+
+public class Olingo4ComponentConsumerTest extends AbstractOlingo4TestSupport {
+
+    private static final String PEOPLE = "People";
+    private static final String TEST_PEOPLE = "People('russellwhyte')";
+    private static final String AIRPORTS = "Airports";
+
+    public Olingo4ComponentConsumerTest() {
+        setUseRouteBuilder(false);
+    }
+
+    @Override
+    public boolean isCreateCamelContextPerClass() {
+        return false;
+    }
+
+    private void addRouteAndStartContext(RouteBuilder builder) throws Exception {
+        context().addRoutes(builder);
+        startCamelContext();
+    }
+
+    /**
+     * Read entity set of the People object
+     * and filter already seen items on subsequent exchanges
+     * Use a delay since the mock endpoint does not always get
+     * the correct number of exchanges before being satisfied.
+     *
+     * Note:
+     * - consumer.splitResults is set to false since this ensures the first returned message
+     *   contains all the results. This is preferred for the purposes of this test. The default
+     *   will mean the first n messages contain the results (where n is the result total) then
+     *   subsequent messages will be empty
+     */
+    @Test
+    public void testConsumerReadFilterAlreadySeen() throws Exception {
+        int expectedEntities = 20;
+        int expectedMsgCount = 3;
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-alreadyseen");
+        mockEndpoint.expectedMinimumMessageCount(expectedMsgCount);
+
+        RouteBuilder builder = new RouteBuilder() {
+            public void configure() {
+                from("olingo4://read/" + PEOPLE + "?consumer.delay=2&consumer.sendEmptyMessageWhenIdle=true&consumer.splitResult=false&filterAlreadySeen=true")
+                    .to("mock:consumer-alreadyseen");
+            };
+        };
+        addRouteAndStartContext(builder);
+
+        mockEndpoint.assertIsSatisfied();
+
+        for (int i = 0; i < expectedMsgCount; ++i) {
+            Object body = mockEndpoint.getExchanges().get(i).getIn().getBody();
+
+            if (i == 0) {
+                //
+                // First polled messages contained all the entities
+                //
+                assertTrue(body instanceof ClientEntitySet);
+                ClientEntitySet set = (ClientEntitySet) body;
+                assertEquals(expectedEntities, set.getEntities().size());
+            } else {
+                //
+                // Subsequent polling messages should be empty
+                // since the filterAlreadySeen property is true
+                //
+                assertNull(body);
+            }
+        }
+    }
+
+    @Test
+    public void testConsumerReadFilterAlreadySeenWithPredicateAndSplitResults() throws Exception {
+        int expectedMsgCount = 3;
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-splitresult-kp-airport");
+        mockEndpoint.expectedMinimumMessageCount(expectedMsgCount);
+
+        RouteBuilder builder = new RouteBuilder() {
+            public void configure() {
+                from("olingo4://read/" + AIRPORTS + "('KSFO')"
+                        + "?filterAlreadySeen=true&"
+                        + "consumer.delay=2&consumer.sendEmptyMessageWhenIdle=true&"
+                        + "consumer.splitResult=true")
+                    .to("mock:consumer-splitresult-kp-airport");
+            };
+        };
+        addRouteAndStartContext(builder);
+
+        mockEndpoint.assertIsSatisfied();
+
+        for (int i = 0; i < expectedMsgCount; ++i) {
+            Object body = mockEndpoint.getExchanges().get(i).getIn().getBody();
+
+            if (i == 0) {
+                //
+                // First polled messages contained all the entities
+                //
+                assertTrue(body instanceof ClientEntity);
+                ClientEntity ksfoEntity = (ClientEntity) body;
+                ClientProperty nameProp = ksfoEntity.getProperty("Name");
+                assertNotNull(nameProp);
+                assertEquals("San Francisco International Airport", nameProp.getValue().toString());
+            } else {
+                //
+                // Subsequent polling messages should be empty
+                // since the filterAlreadySeen property is true
+                //
+                assertNull(body);
+            }
+        }
+    }
+
+    /**
+     * Read entity set of the People object and split the results
+     * into individual messages
+     */
+    @Test
+    public void testConsumerReadSplitResults() throws Exception {
+        int expectedMsgCount = 3;
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-splitresult");
+        mockEndpoint.expectedMinimumMessageCount(expectedMsgCount);
+
+        RouteBuilder builder = new RouteBuilder() {
+            public void configure() {
+                from("olingo4://read/" + PEOPLE + "?consumer.splitResult=true")
+                    .to("mock:consumer-splitresult");
+            };
+        };
+        addRouteAndStartContext(builder);
+
+        mockEndpoint.assertIsSatisfied();
+        //
+        // At least 3 individual messages in the exchange,
+        // each containing a different entity.
+        //
+        for (int i = 0; i < expectedMsgCount; ++i) {
+            Object body = mockEndpoint.getExchanges().get(i).getIn().getBody();
+            assertTrue(body instanceof ClientEntity);
+            ClientEntity entity = (ClientEntity)body;
+            ClientProperty nameProperty = entity.getProperty("UserName");
+            assertNotNull(nameProperty);
+
+            switch(i) {
+            case 0:
+                assertEquals("russellwhyte", nameProperty.getValue().toString());
+                break;
+            case 1:
+                assertEquals("scottketchum", nameProperty.getValue().toString());
+                break;
+            case 2:
+                assertEquals("ronaldmundy", nameProperty.getValue().toString());
+                break;
+            default:
+            }
+        }
+    }
+
+    /**
+     * Read value of the People object and split the results
+     * into individual messages
+     */
+    @Test
+    public void testConsumerReadClientValuesSplitResults() throws Exception {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-splitresult-value");
+        mockEndpoint.expectedMinimumMessageCount(1);
+
+        RouteBuilder builder = new RouteBuilder() {
+            public void configure() {
+                from("olingo4://read/" + TEST_PEOPLE + "/FavoriteFeature?consumer.splitResult=true")
+                    .to("mock:consumer-splitresult-value");
+            };
+        };
+        addRouteAndStartContext(builder);
+
+        mockEndpoint.assertIsSatisfied();
+        //
+        // 1 individual message in the exchange
+        //
+        Object body = mockEndpoint.getExchanges().get(0).getIn().getBody();
+        assertIsInstanceOf(ClientPrimitiveValue.class, body);
+        ClientPrimitiveValue value = (ClientPrimitiveValue) body;
+        assertEquals("Feature1", value.toString());
+    }
+}
diff --git a/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentTest.java b/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentProducerTest.java
similarity index 78%
rename from components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentTest.java
rename to components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentProducerTest.java
index c7d0125..e28bbb3 100644
--- a/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentTest.java
+++ b/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentProducerTest.java
@@ -32,7 +32,6 @@ import org.apache.olingo.client.api.domain.ClientComplexValue;
 import org.apache.olingo.client.api.domain.ClientEntity;
 import org.apache.olingo.client.api.domain.ClientEntitySet;
 import org.apache.olingo.client.api.domain.ClientPrimitiveValue;
-import org.apache.olingo.client.api.domain.ClientProperty;
 import org.apache.olingo.client.api.domain.ClientServiceDocument;
 import org.apache.olingo.client.api.domain.ClientValue;
 import org.apache.olingo.commons.api.Constants;
@@ -52,9 +51,9 @@ import org.slf4j.LoggerFactory;
  * service published on http://services.odata.org/TripPinRESTierService.
  * </p>
  */
-public class Olingo4ComponentTest extends AbstractOlingo4TestSupport {
+public class Olingo4ComponentProducerTest extends AbstractOlingo4TestSupport {
 
-    private static final Logger LOG = LoggerFactory.getLogger(Olingo4ComponentTest.class);
+    private static final Logger LOG = LoggerFactory.getLogger(Olingo4ComponentProducerTest.class);
 
     private static final String PEOPLE = "People";
     private static final String TEST_PEOPLE = "People('russellwhyte')";
@@ -299,53 +298,6 @@ public class Olingo4ComponentTest extends AbstractOlingo4TestSupport {
     }
 
     /**
-     * Read entity set of the People object
-     * and filter already seen items on subsequent exchanges
-     * Use a delay since the mock endpoint does not always get
-     * the correct number of exchanges before being satisfied.
-     *
-     * Note:
-     * - consumer.splitResults is set to false since this ensures the first returned message
-     *   contains all the results. This is preferred for the purposes of this test. The default
-     *   will mean the first n messages contain the results (where n is the result total) then
-     *   subsequent messages will be empty
-     */
-    @Test
-    public void testConsumerReadFilterAlreadySeen() throws Exception {
-        final Map<String, Object> headers = new HashMap<>();
-        String endpoint = "olingo4://read/People?filterAlreadySeen=true&consumer.delay=2&consumer.sendEmptyMessageWhenIdle=true&consumer.splitResult=false";
-        int expectedEntities = 20;
-        int expectedMsgCount = 3;
-        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-alreadyseen");
-        mockEndpoint.expectedMessageCount(expectedMsgCount);
-
-        final ClientEntitySet entities = (ClientEntitySet)requestBodyAndHeaders(endpoint, null, headers);
-        assertNotNull(entities);
-        assertEquals(expectedEntities, entities.getEntities().size());
-
-        mockEndpoint.assertIsSatisfied();
-
-        for (int i = 0; i < expectedMsgCount; ++i) {
-            Object body = mockEndpoint.getExchanges().get(i).getIn().getBody();
-
-            if (i == 0) {
-                //
-                // First polled messages contained all the entities
-                //
-                assertTrue(body instanceof ClientEntitySet);
-                ClientEntitySet set = (ClientEntitySet) body;
-                assertEquals(expectedEntities, set.getEntities().size());
-            } else {
-                //
-                // Subsequent polling messages should be empty
-                // since the filterAlreadySeen property is true
-                //
-                assertNull(body);
-            }
-        }
-    }
-
-    /**
      *
      * Read entity set of the People object
      * and with no filter already seen, all items
@@ -423,75 +375,6 @@ public class Olingo4ComponentTest extends AbstractOlingo4TestSupport {
         }
     }
 
-    /**
-     * Read entity set of the People object and split the results
-     * into individual messages
-     */
-    @Test
-    public void testConsumerReadSplitResults() throws Exception {
-        final Map<String, Object> headers = new HashMap<>();
-        String endpoint = "olingo4://read/People?consumer.splitResult=true";
-        int expectedEntities = 20;
-
-        int expectedMsgCount = 3;
-        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-splitresult");
-        mockEndpoint.expectedMinimumMessageCount(expectedMsgCount);
-
-        final ClientEntitySet entities = (ClientEntitySet)requestBodyAndHeaders(endpoint, null, headers);
-        assertNotNull(entities);
-        assertEquals(expectedEntities, entities.getEntities().size());
-
-        mockEndpoint.assertIsSatisfied();
-        //
-        // At least 3 individual messages in the exchange,
-        // each containing a different entity.
-        //
-        for (int i = 0; i < expectedMsgCount; ++i) {
-            Object body = mockEndpoint.getExchanges().get(i).getIn().getBody();
-            assertTrue(body instanceof ClientEntity);
-            ClientEntity entity = (ClientEntity)body;
-            ClientProperty nameProperty = entity.getProperty("UserName");
-            assertNotNull(nameProperty);
-
-            switch(i) {
-            case 0:
-                assertEquals("russellwhyte", nameProperty.getValue().toString());
-                break;
-            case 1:
-                assertEquals("scottketchum", nameProperty.getValue().toString());
-                break;
-            case 2:
-                assertEquals("ronaldmundy", nameProperty.getValue().toString());
-                break;
-            default:
-            }
-        }
-    }
-    /**
-     * Read value of the People object and split the results
-     * into individual messages
-     */
-    @Test
-    public void testConsumerReadClientValuesSplitResults() throws Exception {
-        final Map<String, Object> headers = new HashMap<>();
-        String endpoint = "olingo4://read/People('russellwhyte')/FavoriteFeature?consumer.splitResult=true";
-
-        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-splitresult-value");
-        mockEndpoint.expectedMinimumMessageCount(1);
-
-        final ClientValue resultValue = requestBodyAndHeaders(endpoint, null, headers);
-        assertIsInstanceOf(ClientValue.class, resultValue);
-
-        mockEndpoint.assertIsSatisfied();
-        //
-        // 1 individual message in the exchange
-        //
-        Object body = mockEndpoint.getExchanges().get(0).getIn().getBody();
-        assertIsInstanceOf(ClientPrimitiveValue.class, body);
-        ClientPrimitiveValue value = (ClientPrimitiveValue) body;
-        assertEquals("Feature1", value.toString());
-    }
-
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
@@ -543,19 +426,6 @@ public class Olingo4ComponentTest extends AbstractOlingo4TestSupport {
                 from("direct:read-people-filterseen")
                     .to("olingo4://read/People?filterAlreadySeen=true")
                     .to("mock:producer-alreadyseen");
-
-                //
-                // Consumer endpoint
-                //
-                from("olingo4://read/People?filterAlreadySeen=true&consumer.delay=2&consumer.sendEmptyMessageWhenIdle=true&consumer.splitResult=false")
-                    .to("mock:consumer-alreadyseen");
-
-                from("olingo4://read/People?consumer.splitResult=true")
-                    .to("mock:consumer-splitresult");
-
-                from("olingo4://read/People('russellwhyte')/FavoriteFeature?consumer.splitResult=true")
-                    .to("mock:consumer-splitresult-value");
-
             }
         };
     }


[camel] 02/03: CAMEL-13316: Fixed CS for Olingo 2

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

acosentino pushed a commit to branch camel-2.24.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 27e9e6d9d4ca72663a83a7f66ddd914d9321ae61
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Wed Mar 20 15:26:52 2019 +0100

    CAMEL-13316: Fixed CS for Olingo 2
---
 .../java/org/apache/camel/component/olingo2/Olingo2ComponentTest.java  | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentTest.java b/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentTest.java
index cdaa7e6..e544b79 100644
--- a/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentTest.java
+++ b/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentTest.java
@@ -121,7 +121,6 @@ public class Olingo2ComponentTest extends AbstractOlingo2TestSupport {
         LOG.info("Manufacturer: {}", properties);
     }
 
-    @SuppressWarnings( "unchecked" )
     @Test
     public void testCreateUpdateDelete() throws Exception {
         final Map<String, Object> data = getEntityData();
@@ -164,7 +163,6 @@ public class Olingo2ComponentTest extends AbstractOlingo2TestSupport {
         return data;
     }
 
-    @SuppressWarnings( "unchecked" )
     @Test
     public void testBatch() throws Exception {
         final List<Olingo2BatchRequest> batchParts = new ArrayList<>();
@@ -301,7 +299,6 @@ public class Olingo2ComponentTest extends AbstractOlingo2TestSupport {
      * Read value of the People object and split the results
      * into individual messages
      */
-    @SuppressWarnings( "unchecked" )
     @Test
     public void testConsumerReadClientValuesSplitResults() throws Exception {
         final Map<String, Object> headers = new HashMap<>();


[camel] 01/03: CAMEL-13316: Olingo components handle value/property results

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

acosentino pushed a commit to branch camel-2.24.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 1aab75fc700a7882b621c60e1f12f825389ef6e4
Author: phantomjinx <p....@phantomjinx.co.uk>
AuthorDate: Mon Mar 18 15:30:17 2019 +0000

    CAMEL-13316: Olingo components handle value/property results
    
    * When split, both olingo components handle results which are values or
      properties rather than entities.
    
    * Provides tests confirming the fix.
---
 .../camel/component/olingo2/Olingo2Consumer.java   |  4 +-
 .../component/olingo2/Olingo2ComponentTest.java    | 51 +++++++++++++++++++---
 .../camel/component/olingo4/Olingo4Consumer.java   |  9 +++-
 .../component/olingo4/Olingo4ComponentTest.java    | 35 ++++++++++++++-
 4 files changed, 89 insertions(+), 10 deletions(-)

diff --git a/components/camel-olingo2/camel-olingo2-component/src/main/java/org/apache/camel/component/olingo2/Olingo2Consumer.java b/components/camel-olingo2/camel-olingo2-component/src/main/java/org/apache/camel/component/olingo2/Olingo2Consumer.java
index e92d96d..d069318 100644
--- a/components/camel-olingo2/camel-olingo2-component/src/main/java/org/apache/camel/component/olingo2/Olingo2Consumer.java
+++ b/components/camel-olingo2/camel-olingo2-component/src/main/java/org/apache/camel/component/olingo2/Olingo2Consumer.java
@@ -144,7 +144,9 @@ public class Olingo2Consumer extends AbstractApiConsumer<Olingo2ApiName, Olingo2
             for (ODataEntry entry : odataFeed.getEntries()) {
                 splitResult.add(entry);
             }
-        } else if (result instanceof ODataEntry) {
+        } else if (result instanceof List) {
+            return result;
+        } else {
             splitResult.add(result);
         }
 
diff --git a/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentTest.java b/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentTest.java
index c60a3d9..cdaa7e6 100644
--- a/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentTest.java
+++ b/components/camel-olingo2/camel-olingo2-component/src/test/java/org/apache/camel/component/olingo2/Olingo2ComponentTest.java
@@ -121,6 +121,7 @@ public class Olingo2ComponentTest extends AbstractOlingo2TestSupport {
         LOG.info("Manufacturer: {}", properties);
     }
 
+    @SuppressWarnings( "unchecked" )
     @Test
     public void testCreateUpdateDelete() throws Exception {
         final Map<String, Object> data = getEntityData();
@@ -163,6 +164,7 @@ public class Olingo2ComponentTest extends AbstractOlingo2TestSupport {
         return data;
     }
 
+    @SuppressWarnings( "unchecked" )
     @Test
     public void testBatch() throws Exception {
         final List<Olingo2BatchRequest> batchParts = new ArrayList<>();
@@ -296,10 +298,42 @@ public class Olingo2ComponentTest extends AbstractOlingo2TestSupport {
     }
 
     /**
-     *
-     * Read entity set of the People object
-     * and with no filter already seen, all items
-     * should be present in each message
+     * Read value of the People object and split the results
+     * into individual messages
+     */
+    @SuppressWarnings( "unchecked" )
+    @Test
+    public void testConsumerReadClientValuesSplitResults() throws Exception {
+        final Map<String, Object> headers = new HashMap<>();
+        String endpoint = "olingo2://read/Manufacturers('1')/Address?consumer.splitResult=true";
+
+        this.context.setTracing(true);
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-value");
+        mockEndpoint.expectedMinimumMessageCount(1);
+        mockEndpoint.setResultWaitTime(60000);
+
+        final Map<String, Object> resultValue = requestBodyAndHeaders(endpoint, null, headers);
+        assertNotNull(resultValue);
+
+        mockEndpoint.assertIsSatisfied();
+        //
+        // 1 individual message in the exchange
+        //
+        Object body = mockEndpoint.getExchanges().get(0).getIn().getBody();
+        assertIsInstanceOf(Map.class, body);
+        Map<String, Object> value = (Map<String, Object>) body;
+        Object addrObj = value.get("Address");
+        assertIsInstanceOf(Map.class, addrObj);
+        Map<String, Object> addrMap = (Map<String, Object>) addrObj;
+        assertEquals("70173", addrMap.get("ZipCode"));
+        assertEquals("Star Street 137", addrMap.get("Street"));
+        assertEquals("Germany", addrMap.get("Country"));
+        assertEquals("Stuttgart", addrMap.get("City"));
+    }
+
+    /**
+     * Read entity set of the People object and with no filter already seen, all
+     * items should be present in each message
      *
      * @throws Exception
      */
@@ -473,9 +507,14 @@ public class Olingo2ComponentTest extends AbstractOlingo2TestSupport {
                 //
                 // Consumer endpoint
                 //
-                from("olingo2://read/Manufacturers?filterAlreadySeen=true&consumer.delay=2&consumer.sendEmptyMessageWhenIdle=true&consumer.splitResult=false").to("mock:consumer-alreadyseen");
+                from("olingo2://read/Manufacturers?filterAlreadySeen=true&consumer.delay=2&consumer.sendEmptyMessageWhenIdle=true&consumer.splitResult=false")
+                    .to("mock:consumer-alreadyseen");
+
+                from("olingo2://read/Manufacturers?consumer.splitResult=true")
+                    .to("mock:consumer-splitresult");
 
-                from("olingo2://read/Manufacturers?consumer.splitResult=true").to("mock:consumer-splitresult");
+                from("olingo2://read/Manufacturers('1')/Address?consumer.splitResult=true")
+                    .to("mock:consumer-value");
             }
         };
     }
diff --git a/components/camel-olingo4/camel-olingo4-component/src/main/java/org/apache/camel/component/olingo4/Olingo4Consumer.java b/components/camel-olingo4/camel-olingo4-component/src/main/java/org/apache/camel/component/olingo4/Olingo4Consumer.java
index 4cee0a5..8c72db4 100644
--- a/components/camel-olingo4/camel-olingo4-component/src/main/java/org/apache/camel/component/olingo4/Olingo4Consumer.java
+++ b/components/camel-olingo4/camel-olingo4-component/src/main/java/org/apache/camel/component/olingo4/Olingo4Consumer.java
@@ -29,6 +29,7 @@ import org.apache.camel.component.olingo4.internal.Olingo4ApiName;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.component.AbstractApiConsumer;
 import org.apache.camel.util.component.ApiConsumerHelper;
+import org.apache.olingo.client.api.domain.ClientCollectionValue;
 import org.apache.olingo.client.api.domain.ClientEntity;
 import org.apache.olingo.client.api.domain.ClientEntitySet;
 import org.apache.olingo.client.api.domain.ClientValue;
@@ -156,7 +157,13 @@ public class Olingo4Consumer extends AbstractApiConsumer<Olingo4ApiName, Olingo4
                 }
                 splitResult.add(entity);
             }
-        } else if (result instanceof ClientEntity) {
+        } else if (result instanceof ClientValue && ((ClientValue) result).isCollection()) {
+            ClientValue value = (ClientValue) result;
+            ClientCollectionValue<ClientValue> collection = value.asCollection();
+            collection.forEach(v -> {
+                splitResult.add(v);
+            });
+        } else {
             splitResult.add(result);
         }
 
diff --git a/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentTest.java b/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentTest.java
index dfafcbe..c7d0125 100644
--- a/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentTest.java
+++ b/components/camel-olingo4/camel-olingo4-component/src/test/java/org/apache/camel/component/olingo4/Olingo4ComponentTest.java
@@ -34,6 +34,7 @@ import org.apache.olingo.client.api.domain.ClientEntitySet;
 import org.apache.olingo.client.api.domain.ClientPrimitiveValue;
 import org.apache.olingo.client.api.domain.ClientProperty;
 import org.apache.olingo.client.api.domain.ClientServiceDocument;
+import org.apache.olingo.client.api.domain.ClientValue;
 import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.ex.ODataError;
@@ -466,6 +467,30 @@ public class Olingo4ComponentTest extends AbstractOlingo4TestSupport {
             }
         }
     }
+    /**
+     * Read value of the People object and split the results
+     * into individual messages
+     */
+    @Test
+    public void testConsumerReadClientValuesSplitResults() throws Exception {
+        final Map<String, Object> headers = new HashMap<>();
+        String endpoint = "olingo4://read/People('russellwhyte')/FavoriteFeature?consumer.splitResult=true";
+
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-splitresult-value");
+        mockEndpoint.expectedMinimumMessageCount(1);
+
+        final ClientValue resultValue = requestBodyAndHeaders(endpoint, null, headers);
+        assertIsInstanceOf(ClientValue.class, resultValue);
+
+        mockEndpoint.assertIsSatisfied();
+        //
+        // 1 individual message in the exchange
+        //
+        Object body = mockEndpoint.getExchanges().get(0).getIn().getBody();
+        assertIsInstanceOf(ClientPrimitiveValue.class, body);
+        ClientPrimitiveValue value = (ClientPrimitiveValue) body;
+        assertEquals("Feature1", value.toString());
+    }
 
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
@@ -522,9 +547,15 @@ public class Olingo4ComponentTest extends AbstractOlingo4TestSupport {
                 //
                 // Consumer endpoint
                 //
-                from("olingo4://read/People?filterAlreadySeen=true&consumer.delay=2&consumer.sendEmptyMessageWhenIdle=true&consumer.splitResult=false").to("mock:consumer-alreadyseen");
+                from("olingo4://read/People?filterAlreadySeen=true&consumer.delay=2&consumer.sendEmptyMessageWhenIdle=true&consumer.splitResult=false")
+                    .to("mock:consumer-alreadyseen");
+
+                from("olingo4://read/People?consumer.splitResult=true")
+                    .to("mock:consumer-splitresult");
+
+                from("olingo4://read/People('russellwhyte')/FavoriteFeature?consumer.splitResult=true")
+                    .to("mock:consumer-splitresult-value");
 
-                from("olingo4://read/People?consumer.splitResult=true").to("mock:consumer-splitresult");
             }
         };
     }