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 2019/08/13 04:24:47 UTC
[camel] branch master updated: CAMEL-13861: Fixes missing logic
producing empty messages
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push:
new 53f415b CAMEL-13861: Fixes missing logic producing empty messages
53f415b is described below
commit 53f415b516c42224574cd6dcf0217da057171b4f
Author: phantomjinx <p....@phantomjinx.co.uk>
AuthorDate: Fri Aug 9 10:37:14 2019 +0100
CAMEL-13861: Fixes missing logic producing empty messages
* Olingo[*]Consumer
* Tests for null results as well as empty collections. Return 0 accordingly
* Adds and updates tests to assume no empty messages unless the
consumer.sendEmptyMessageWhenIdle property has been configured
---
.../camel/component/olingo2/Olingo2Consumer.java | 3 +-
.../olingo2/Olingo2ComponentConsumerTest.java | 111 +++++++++++++++-
.../camel/component/olingo4/Olingo4Consumer.java | 3 +-
.../olingo4/Olingo4ComponentConsumerTest.java | 144 ++++++++++++++++++++-
4 files changed, 257 insertions(+), 4 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 333e45e..ac0c5ee 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
@@ -94,7 +94,8 @@ public class Olingo2Consumer extends AbstractApiConsumer<Olingo2ApiName, Olingo2
//
// Allow consumer idle properties to properly handle an empty polling response
//
- if (result[0] instanceof ODataFeed && (((ODataFeed) result[0]).getEntries().isEmpty())) {
+ if ((result[0] == null)
+ || (result[0] instanceof ODataFeed && (((ODataFeed) result[0]).getEntries().isEmpty()))) {
return 0;
} else {
int processed = ApiConsumerHelper.getResultsProcessed(this, result[0], isSplitResult());
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
index a3a61c8..0af1b81 100644
--- 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
@@ -119,8 +119,67 @@ public class Olingo2ComponentConsumerTest 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.
+ * - consumer.sendEmptyMessageWhenIdle is set to false so only 1 message should
+ * even be returned.
+ */
+ @Test
+ public void testConsumerReadFilterAlreadySeenNoEmptyMsgs() throws Exception {
+ int expectedMsgCount = 1;
+ MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-alreadyseen");
+ //
+ // Add 1 to count since we want to wait for full result time
+ // before asserting that only 1 message has been delivered
+ //
+ mockEndpoint.expectedMinimumMessageCount(expectedMsgCount + 1);
+ mockEndpoint.setResultWaitTime(6000L);
+
+ RouteBuilder builder = new RouteBuilder() {
+ public void configure() {
+ from("olingo2://read/Manufacturers?filterAlreadySeen=true&"
+ + "consumer.delay=2&consumer.sendEmptyMessageWhenIdle=false&"
+ + "consumer.splitResult=false")
+ .to("mock:consumer-alreadyseen");
+ };
+ };
+ addRouteAndStartContext(builder);
+
+ //
+ // Want to wait for entire result time & there should
+ // be exactly 1 exchange transmitted to the endpoint
+ //
+ mockEndpoint.assertIsNotSatisfied();
+
+ // Only 1 exchange so this is good!
+ assertEquals(1, mockEndpoint.getExchanges().size());
+ Object body = mockEndpoint.getExchanges().get(0).getIn().getBody();
+
+ //
+ // Only polled message contains all the entities
+ //
+ assertTrue(body instanceof ODataFeed);
+ ODataFeed set = (ODataFeed) body;
+ assertTrue(set.getEntries().size() > 0);
+ }
+
+ /**
+ * WithPredicate in address
+ * FilterAlreadySeen: true
+ * SplitResults: true
+ * consumer.sendEmptyMessageWhenIdle: true
+ *
+ * @throws Exception
+ */
@Test
- public void testConsumerReadFilterAlreadySeenWithPredicateAndSplitResults() throws Exception {
+ public void testConsumerReadFilterAlreadySeenWithPredicate1() throws Exception {
int expectedMsgCount = 3;
MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-splitresult-kp-manufacturer");
mockEndpoint.expectedMinimumMessageCount(expectedMsgCount);
@@ -160,6 +219,56 @@ public class Olingo2ComponentConsumerTest extends AbstractOlingo2TestSupport {
}
/**
+ * WithPredicate in address
+ * FilterAlreadySeen: true
+ * SplitResults: true
+ * consumer.sendEmptyMessageWhenIdle: false
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testConsumerReadFilterAlreadySeenWithPredicate2() throws Exception {
+ int expectedMsgCount = 1;
+ MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-splitresult-kp-manufacturer");
+
+ //
+ // Add 1 to count since we want to wait for full result time
+ // before asserting that only 1 message has been delivered
+ //
+ mockEndpoint.expectedMinimumMessageCount(expectedMsgCount + 1);
+ mockEndpoint.setResultWaitTime(6000L);
+
+ RouteBuilder builder = new RouteBuilder() {
+ public void configure() {
+ from("olingo2://read/Manufacturers('1')?filterAlreadySeen=true&"
+ + "consumer.delay=2&consumer.sendEmptyMessageWhenIdle=false&"
+ + "consumer.splitResult=true")
+ .to("mock:consumer-splitresult-kp-manufacturer");
+ };
+ };
+ addRouteAndStartContext(builder);
+
+ //
+ // Want to wait for entire result time & there should
+ // be exactly 1 exchange transmitted to the endpoint
+ //
+ mockEndpoint.assertIsNotSatisfied();
+
+ // Only 1 exchange so this is good!
+ assertEquals(1, mockEndpoint.getExchanges().size());
+
+ Object body = mockEndpoint.getExchanges().get(0).getIn().getBody();
+ //
+ // Only polled message contains the entity
+ //
+ assertTrue(body instanceof ODataEntry);
+ ODataEntry entry = (ODataEntry) body;
+ Object nameValue = entry.getProperties().get("Name");
+ assertNotNull(nameValue);
+ assertEquals("Star Powered Racing", nameValue.toString());
+ }
+
+ /**
* Read value of the People object and split the results
* into individual messages
*/
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 b147108..778e0cb 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
@@ -99,7 +99,8 @@ public class Olingo4Consumer extends AbstractApiConsumer<Olingo4ApiName, Olingo4
//
// Allow consumer idle properties to properly handle an empty polling response
//
- if (result[0] instanceof ClientEntitySet && (((ClientEntitySet) result[0]).getEntities().isEmpty())) {
+ if ((result[0] == null)
+ || (result[0] instanceof ClientEntitySet && (((ClientEntitySet) result[0]).getEntities().isEmpty()))) {
return 0;
} else {
int processed = ApiConsumerHelper.getResultsProcessed(this, result[0], isSplitResult());
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
index b288f2b..c81b174 100644
--- 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
@@ -47,6 +47,39 @@ public class Olingo4ComponentConsumerTest extends AbstractOlingo4TestSupport {
startCamelContext();
}
+ @Test
+ public void testConsumerQueryWithExpand() throws Exception {
+ int expectedMsgCount = 1;
+ MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-query");
+ mockEndpoint.expectedMinimumMessageCount(expectedMsgCount);
+
+ RouteBuilder builder = new RouteBuilder() {
+ public void configure() {
+ from("olingo4://read/" + PEOPLE + "?"
+ + "$filter=LastName eq 'Whyte'&$expand=Trips")
+ .to("mock:consumer-query");
+ };
+ };
+ 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 e = (ClientEntity) body;
+ ClientProperty nameProp = e.getProperty("UserName");
+ assertNotNull(nameProp);
+ assertEquals("russellwhyte", nameProp.getValue().toString());
+ }
+ }
+ }
+
/**
* Read entity set of the People object
* and filter already seen items on subsequent exchanges
@@ -96,8 +129,66 @@ public class Olingo4ComponentConsumerTest 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.
+ * - consumer.sendEmptyMessageWhenIdle is set to false so only 1 message should
+ * even be returned.
+ */
+ @Test
+ public void testConsumerReadFilterAlreadySeenNoEmptyMsgs() throws Exception {
+ int expectedEntities = 20;
+ int expectedMsgCount = 1;
+ MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-alreadyseen");
+ //
+ // Add 1 to count since we want to wait for full result time
+ // before asserting that only 1 message has been delivered
+ //
+ mockEndpoint.expectedMinimumMessageCount(expectedMsgCount + 1);
+ mockEndpoint.setResultWaitTime(6000L);
+
+ RouteBuilder builder = new RouteBuilder() {
+ public void configure() {
+ from("olingo4://read/" + PEOPLE + "?consumer.delay=2&consumer.sendEmptyMessageWhenIdle=false&consumer.splitResult=false&filterAlreadySeen=true")
+ .to("mock:consumer-alreadyseen");
+ };
+ };
+ addRouteAndStartContext(builder);
+
+ //
+ // Want to wait for entire result time & there should
+ // be exactly 1 exchange transmitted to the endpoint
+ //
+ mockEndpoint.assertIsNotSatisfied();
+
+ // Only 1 exchange so this is good!
+ assertEquals(1, mockEndpoint.getExchanges().size());
+ Object body = mockEndpoint.getExchanges().get(0).getIn().getBody();
+
+ //
+ // Only polled message contains all the entities
+ //
+ assertTrue(body instanceof ClientEntitySet);
+ ClientEntitySet set = (ClientEntitySet) body;
+ assertEquals(expectedEntities, set.getEntities().size());
+ }
+
+ /**
+ * WithPredicate in address
+ * FilterAlreadySeen: true
+ * SplitResults: true
+ * consumer.sendEmptyMessageWhenIdle: true
+ *
+ * @throws Exception
+ */
@Test
- public void testConsumerReadFilterAlreadySeenWithPredicateAndSplitResults() throws Exception {
+ public void testConsumerReadFilterAlreadySeenWithPredicate1() throws Exception {
int expectedMsgCount = 3;
MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-splitresult-kp-airport");
mockEndpoint.expectedMinimumMessageCount(expectedMsgCount);
@@ -138,6 +229,57 @@ public class Olingo4ComponentConsumerTest extends AbstractOlingo4TestSupport {
}
/**
+ * WithPredicate in address
+ * FilterAlreadySeen: true
+ * SplitResults: true
+ * consumer.sendEmptyMessageWhenIdle: false
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testConsumerReadFilterAlreadySeenWithPredicate2() throws Exception {
+ int expectedMsgCount = 1;
+ MockEndpoint mockEndpoint = getMockEndpoint("mock:consumer-splitresult-kp-airport");
+
+ //
+ // Add 1 to count since we want to wait for full result time
+ // before asserting that only 1 message has been delivered
+ //
+ mockEndpoint.expectedMinimumMessageCount(expectedMsgCount + 1);
+ mockEndpoint.setResultWaitTime(6000L);
+
+ RouteBuilder builder = new RouteBuilder() {
+ public void configure() {
+ from("olingo4://read/" + AIRPORTS + "('KSFO')"
+ + "?filterAlreadySeen=true&"
+ + "consumer.delay=2&consumer.sendEmptyMessageWhenIdle=false&"
+ + "consumer.splitResult=true")
+ .to("mock:consumer-splitresult-kp-airport");
+ };
+ };
+ addRouteAndStartContext(builder);
+
+ //
+ // Want to wait for entire result time & there should
+ // be exactly 1 exchange transmitted to the endpoint
+ //
+ mockEndpoint.assertIsNotSatisfied();
+
+ // Only 1 exchange so this is good!
+ assertEquals(1, mockEndpoint.getExchanges().size());
+
+ Object body = mockEndpoint.getExchanges().get(0).getIn().getBody();
+ //
+ // Only polled message contains the entity
+ //
+ assertTrue(body instanceof ClientEntity);
+ ClientEntity ksfoEntity = (ClientEntity) body;
+ ClientProperty nameProp = ksfoEntity.getProperty("Name");
+ assertNotNull(nameProp);
+ assertEquals("San Francisco International Airport", nameProp.getValue().toString());
+ }
+
+ /**
* Read entity set of the People object and split the results
* into individual messages
*/