Repository: camel Updated Branches: refs/heads/master e82c8b8f3 -> 2b9caff09
CAMEL-10728 fix handling of BasicDBList and allow better use of multi insert. Context: camel-mongodb, multi insert. Handle the case where the input is a BasicDBList. Adds a configuration header to tell the component to avoid trying to convert the body to a DBObject when the user knows a multi insert is needed ("CamelMongoDbMultiInsert"). See https://issues.apache.org/jira/browse/CAMEL-10504 https://issues.apache.org/jira/browse/CAMEL-10728 Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/2b9caff0 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/2b9caff0 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/2b9caff0 Branch: refs/heads/master Commit: 2b9caff09bb03419f763328d340cd5ac3a342bbf Parents: e82c8b8 Author: Damien Bonvillain <d.bonvill...@groupeonepoint.com> Authored: Wed May 17 17:44:16 2017 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Wed May 24 10:16:12 2017 +0200 ---------------------------------------------------------------------- .../component/mongodb/MongoDbConstants.java | 1 + .../component/mongodb/MongoDbProducer.java | 42 +++++++++++---- .../converters/MongoDbBasicConverters.java | 14 +++++ .../mongodb/MongoDbOperationsTest.java | 55 ++++++++++++++++++++ .../mongodb/mongoBasicOperationsTest.xml | 8 +++ 5 files changed, 110 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/2b9caff0/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/MongoDbConstants.java ---------------------------------------------------------------------- diff --git a/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/MongoDbConstants.java b/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/MongoDbConstants.java index 446a662..88cf672 100644 --- a/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/MongoDbConstants.java +++ b/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/MongoDbConstants.java @@ -26,6 +26,7 @@ public final class MongoDbConstants { public static final String NUM_TO_SKIP = "CamelMongoDbNumToSkip"; public static final String INSERT_RECORDS_AFFECTED = "CamelMongoDbInsertRecordsAffected"; public static final String MULTIUPDATE = "CamelMongoDbMultiUpdate"; + public static final String MULTIINSERT = "CamelMongoDbMultiInsert"; public static final String UPSERT = "CamelMongoDbUpsert"; public static final String RECORDS_AFFECTED = "CamelMongoDbRecordsAffected"; public static final String SORT_BY = "CamelMongoDbSortBy"; http://git-wip-us.apache.org/repos/asf/camel/blob/2b9caff0/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/MongoDbProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/MongoDbProducer.java b/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/MongoDbProducer.java index 814315d..7cef8c3 100644 --- a/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/MongoDbProducer.java +++ b/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/MongoDbProducer.java @@ -382,18 +382,22 @@ public class MongoDbProducer extends DefaultProducer { private Function<Exchange, Object> createDoInsert() { return exchange1 -> { MongoCollection<BasicDBObject> dbCol = calculateCollection(exchange1); - boolean singleInsert = true; - Object insert = exchange1.getIn().getBody(DBObject.class); - // body could not be converted to DBObject, check to see if it's of type List<DBObject> - if (insert == null) { - insert = exchange1.getIn().getBody(List.class); - // if the body of type List was obtained, ensure that all items are of type DBObject and cast the List to List<DBObject> - if (insert != null) { + boolean singleInsert = !exchange1.getIn().getHeader(MongoDbConstants.MULTIINSERT, Boolean.FALSE, Boolean.class); + + Object insert = null; + + if (singleInsert) { + insert = exchange1.getIn().getBody(DBObject.class); + if (insert == null) { + // previous behavior: + // body could not be converted to DBObject, check to see if it's of type List<DBObject> + insert = getMultiInsertBody(exchange1); + singleInsert = false; + } else if (insert instanceof BasicDBList) { singleInsert = false; - insert = attemptConvertToList((List) insert, exchange1); - } else { - throw new CamelMongoDbException("MongoDB operation = insert, Body is not conversible to type DBObject nor List<DBObject>"); } + } else { + insert = getMultiInsertBody(exchange1); } if (singleInsert) { @@ -401,6 +405,7 @@ public class MongoDbProducer extends DefaultProducer { dbCol.insertOne(insertObject); exchange1.getIn().setHeader(MongoDbConstants.OID, insertObject.get("_id")); } else { + @SuppressWarnings("unchecked") List<BasicDBObject> insertObjects = (List<BasicDBObject>) insert; dbCol.insertMany(insertObjects); List<Object> objectIdentification = new ArrayList<>(insertObjects.size()); @@ -411,6 +416,23 @@ public class MongoDbProducer extends DefaultProducer { }; } + private Object getMultiInsertBody(Exchange exchange1) { + Object insert; + // we try List first, because it should be the common case + insert = exchange1.getIn().getBody(List.class); + if (insert != null) { + // if the body of type List was obtained, ensure that all items are of type DBObject and cast the List to List<DBObject> + insert = attemptConvertToList((List<?>) insert, exchange1); + } else { + insert = exchange1.getIn().getBody(BasicDBList.class); + } + + if (insert == null) { + throw new CamelMongoDbException("MongoDB operation = insert, Body is not conversible to type DBObject nor List<DBObject>"); + } + return insert; + } + private Function<Exchange, Object> createDoUpdate() { return exchange1 -> { try { http://git-wip-us.apache.org/repos/asf/camel/blob/2b9caff0/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/converters/MongoDbBasicConverters.java ---------------------------------------------------------------------- diff --git a/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/converters/MongoDbBasicConverters.java b/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/converters/MongoDbBasicConverters.java index 7fac3c2..9c9c70e 100644 --- a/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/converters/MongoDbBasicConverters.java +++ b/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/converters/MongoDbBasicConverters.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.util.Map; import com.fasterxml.jackson.databind.ObjectMapper; +import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; import com.mongodb.util.JSON; @@ -69,6 +70,19 @@ public final class MongoDbBasicConverters { return answer; } + + @Converter + public static BasicDBList fromStringToBasicDBList(String s) { + BasicDBList answer = null; + try { + answer = (BasicDBList) JSON.parse(s); + } catch (Exception e) { + LOG.warn("String -> BasicDBList conversion selected, but the following exception occurred. Returning null.", e); + } + + return answer; + } + @Converter public static BasicDBObject fromStringToBasicDBObject(String s) { BasicDBObject answer = null; http://git-wip-us.apache.org/repos/asf/camel/blob/2b9caff0/components/camel-mongodb/src/test/java/org/apache/camel/component/mongodb/MongoDbOperationsTest.java ---------------------------------------------------------------------- diff --git a/components/camel-mongodb/src/test/java/org/apache/camel/component/mongodb/MongoDbOperationsTest.java b/components/camel-mongodb/src/test/java/org/apache/camel/component/mongodb/MongoDbOperationsTest.java index 42ef53c..ee4a411 100644 --- a/components/camel-mongodb/src/test/java/org/apache/camel/component/mongodb/MongoDbOperationsTest.java +++ b/components/camel-mongodb/src/test/java/org/apache/camel/component/mongodb/MongoDbOperationsTest.java @@ -27,6 +27,8 @@ import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; import com.mongodb.util.JSON; +import de.flapdoodle.embed.process.collections.Collections; + import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; @@ -69,6 +71,57 @@ public class MongoDbOperationsTest extends AbstractMongoDbTest { } @Test + public void testMultiInsertStringFromDBListNoHeader() throws Exception { + assertEquals(0, testCollection.count()); + Object result = template.requestBody("direct:insert", "[{\"_id\":\"testInsertString2\", \"scientist\":\"Einstein\"}, " + + "{\"_id\":\"testInsertString3\", \"scientist\":\"Einstein Too\"}]"); + assertTrue(result instanceof List); + DBObject b = testCollection.find(new BasicDBObject("_id", "testInsertString2")).first(); + assertNotNull("No record with 'testInsertString2' _id", b); + b = testCollection.find(new BasicDBObject("_id", "testInsertString3")).first(); + assertNotNull("No record with 'testInsertString3' _id", b); + } + + @Test + public void testMultiInsertStringFromListNoHeader() throws Exception { + assertEquals(0, testCollection.count()); + Object result = template.requestBody("direct:insert", + Collections.newArrayList("{\"_id\":\"testInsertString4\", \"scientist\":\"Einstein\"}", + "{\"_id\":\"testInsertString5\", \"scientist\":\"Einstein Too\"}")); + assertTrue(result instanceof List); + DBObject b = testCollection.find(new BasicDBObject("_id", "testInsertString4")).first(); + assertNotNull("No record with 'testInsertString4' _id", b); + b = testCollection.find(new BasicDBObject("_id", "testInsertString5")).first(); + assertNotNull("No record with 'testInsertString5' _id", b); + } + + + @Test + public void testMultiInsertStringFromDBListHeader() throws Exception { + assertEquals(0, testCollection.count()); + Object result = template.requestBody("direct:multiinsert", "[{\"_id\":\"testInsertString6\", \"scientist\":\"Einstein\"}, " + + "{\"_id\":\"testInsertString7\", \"scientist\":\"Einstein Too\"}]"); + assertTrue(result instanceof List); + DBObject b = testCollection.find(new BasicDBObject("_id", "testInsertString6")).first(); + assertNotNull("No record with 'testInsertString6' _id", b); + b = testCollection.find(new BasicDBObject("_id", "testInsertString7")).first(); + assertNotNull("No record with 'testInsertString7' _id", b); + } + + @Test + public void testMultiInsertStringFromListHeader() throws Exception { + assertEquals(0, testCollection.count()); + Object result = template.requestBody("direct:multiinsert", + Collections.newArrayList("{\"_id\":\"testInsertString8\", \"scientist\":\"Einstein\"}", + "{\"_id\":\"testInsertString9\", \"scientist\":\"Einstein Too\"}")); + assertTrue(result instanceof List); + DBObject b = testCollection.find(new BasicDBObject("_id", "testInsertString8")).first(); + assertNotNull("No record with 'testInsertString8' _id", b); + b = testCollection.find(new BasicDBObject("_id", "testInsertString9")).first(); + assertNotNull("No record with 'testInsertString9' _id", b); + } + + @Test public void testStoreOidOnInsert() throws Exception { DBObject dbObject = new BasicDBObject(); ObjectId oid = template.requestBody("direct:testStoreOidOnInsert", dbObject, ObjectId.class); @@ -267,6 +320,8 @@ public class MongoDbOperationsTest extends AbstractMongoDbTest { public void configure() { from("direct:count").to("mongodb:myDb?database={{mongodb.testDb}}&collection={{mongodb.testCollection}}&operation=count&dynamicity=true"); + from("direct:multiinsert").setHeader(MongoDbConstants.MULTIINSERT).constant(true). + to("mongodb:myDb?database={{mongodb.testDb}}&collection={{mongodb.testCollection}}&operation=insert&writeConcern=SAFE"); from("direct:insert").to("mongodb:myDb?database={{mongodb.testDb}}&collection={{mongodb.testCollection}}&operation=insert&writeConcern=SAFE"); from("direct:testStoreOidOnInsert").to("mongodb:myDb?database={{mongodb.testDb}}&collection={{mongodb.testCollection}}&operation=insert&writeConcern=SAFE"). setBody().header(MongoDbConstants.OID); http://git-wip-us.apache.org/repos/asf/camel/blob/2b9caff0/components/camel-mongodb/src/test/resources/org/apache/camel/component/mongodb/mongoBasicOperationsTest.xml ---------------------------------------------------------------------- diff --git a/components/camel-mongodb/src/test/resources/org/apache/camel/component/mongodb/mongoBasicOperationsTest.xml b/components/camel-mongodb/src/test/resources/org/apache/camel/component/mongodb/mongoBasicOperationsTest.xml index 8943047..bc2eff1 100644 --- a/components/camel-mongodb/src/test/resources/org/apache/camel/component/mongodb/mongoBasicOperationsTest.xml +++ b/components/camel-mongodb/src/test/resources/org/apache/camel/component/mongodb/mongoBasicOperationsTest.xml @@ -36,6 +36,14 @@ <from uri="direct:insert" /> <to uri="mongodb:myDb?database={{mongodb.testDb}}&collection={{mongodb.testCollection}}&operation=insert&writeConcern=SAFE" /> </route> + + <route> + <from uri="direct:multiinsert" /> + <setHeader headerName="CamelMongoDbMultiInsert"> + <constant>true</constant> + </setHeader> + <to uri="mongodb:myDb?database={{mongodb.testDb}}&collection={{mongodb.testCollection}}&operation=insert&writeConcern=SAFE" /> + </route> <route> <from uri="direct:testStoreOidOnInsert" />