CAMEL-11455: Fixed camel-mongodb3 type converters which was implemented wrong and could lead to stop working on first parsing error.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/54073597 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/54073597 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/54073597 Branch: refs/heads/master Commit: 54073597bdee87a035a569c74c4e9fb465a866f2 Parents: dadbbf3 Author: Claus Ibsen <davscl...@apache.org> Authored: Sun Jul 23 11:34:27 2017 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Sun Jul 23 11:34:27 2017 +0200 ---------------------------------------------------------------------- .../converters/MongoDbBasicConverters.java | 37 +-------- .../converters/MongoDbFallbackConverter.java | 80 ++++++++++++++++++++ .../services/org/apache/camel/TypeConverter | 3 +- .../mongodb3/MongoDbExceptionHandlingTest.java | 21 +++++ 4 files changed, 106 insertions(+), 35 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/54073597/components/camel-mongodb3/src/main/java/org/apache/camel/component/mongodb3/converters/MongoDbBasicConverters.java ---------------------------------------------------------------------- diff --git a/components/camel-mongodb3/src/main/java/org/apache/camel/component/mongodb3/converters/MongoDbBasicConverters.java b/components/camel-mongodb3/src/main/java/org/apache/camel/component/mongodb3/converters/MongoDbBasicConverters.java index 0bf2074..c03345f 100644 --- a/components/camel-mongodb3/src/main/java/org/apache/camel/component/mongodb3/converters/MongoDbBasicConverters.java +++ b/components/camel-mongodb3/src/main/java/org/apache/camel/component/mongodb3/converters/MongoDbBasicConverters.java @@ -18,15 +18,12 @@ package org.apache.camel.component.mongodb3.converters; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; -import com.fasterxml.jackson.databind.ObjectMapper; - import org.apache.camel.Converter; import org.apache.camel.Exchange; import org.apache.camel.converter.IOConverter; @@ -52,10 +49,6 @@ public final class MongoDbBasicConverters { private static final Logger LOG = LoggerFactory.getLogger(MongoDbBasicConverters.class); - // Jackson's ObjectMapper is thread-safe, so no need to create a pool nor - // synchronize access to it - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - private MongoDbBasicConverters() { } @@ -71,23 +64,16 @@ public final class MongoDbBasicConverters { @Converter public static Document fromStringToDocument(String s) { - Document answer = null; - try { - answer = Document.parse(s); - } catch (Exception e) { - LOG.warn("String -> Document conversion selected, but the following exception occurred. Returning null.", e); - } - - return answer; + return Document.parse(s); } @Converter - public static Document fromFileToDocument(File f, Exchange exchange) throws FileNotFoundException { + public static Document fromFileToDocument(File f, Exchange exchange) throws Exception { return fromInputStreamToDocument(new FileInputStream(f), exchange); } @Converter - public static Document fromInputStreamToDocument(InputStream is, Exchange exchange) { + public static Document fromInputStreamToDocument(InputStream is, Exchange exchange) throws Exception { Document answer = null; try { byte[] input = IOConverter.toBytes(is); @@ -100,8 +86,6 @@ public final class MongoDbBasicConverters { } else { answer = Document.parse(IOConverter.toString(input, exchange)); } - } catch (Exception e) { - LOG.warn("String -> Document conversion selected, but the following exception occurred. Returning null.", e); } finally { // we need to make sure to close the input stream IOHelper.close(is, "InputStream", LOG); @@ -127,21 +111,6 @@ public final class MongoDbBasicConverters { } @Converter - public static Document fromAnyObjectToDocument(Object value) { - Document answer; - try { - @SuppressWarnings("unchecked") - Map<String, Object> m = OBJECT_MAPPER.convertValue(value, Map.class); - answer = new Document(m); - } catch (Exception e) { - LOG.warn("Conversion has fallen back to generic Object -> Document, but unable to convert type {}. Returning null. {}", value.getClass().getCanonicalName(), - e.getClass().getCanonicalName() + ": " + e.getMessage()); - return null; - } - return answer; - } - - @Converter public static List<Bson> fromStringToList(String value) { final CodecRegistry codecRegistry = CodecRegistries.fromProviders(Arrays.asList(new ValueCodecProvider(), new BsonValueCodecProvider(), new DocumentCodecProvider())); http://git-wip-us.apache.org/repos/asf/camel/blob/54073597/components/camel-mongodb3/src/main/java/org/apache/camel/component/mongodb3/converters/MongoDbFallbackConverter.java ---------------------------------------------------------------------- diff --git a/components/camel-mongodb3/src/main/java/org/apache/camel/component/mongodb3/converters/MongoDbFallbackConverter.java b/components/camel-mongodb3/src/main/java/org/apache/camel/component/mongodb3/converters/MongoDbFallbackConverter.java new file mode 100644 index 0000000..10962cf --- /dev/null +++ b/components/camel-mongodb3/src/main/java/org/apache/camel/component/mongodb3/converters/MongoDbFallbackConverter.java @@ -0,0 +1,80 @@ +/** + * 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.mongodb3.converters; + +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; +import org.apache.camel.Converter; +import org.apache.camel.Exchange; +import org.apache.camel.FallbackConverter; +import org.apache.camel.InvalidPayloadException; +import org.apache.camel.spi.TypeConverterRegistry; + +@Converter +public final class MongoDbFallbackConverter { + + // Jackson's ObjectMapper is thread-safe, so no need to create a pool nor synchronize access to it + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + private MongoDbFallbackConverter() { + } + + @FallbackConverter + public static Object convertTo(Class<?> type, Exchange exchange, Object value, TypeConverterRegistry registry) + throws InvalidPayloadException { + + // if the source is a string and we attempt to convert to one of the known mongodb json classes then try that + if (String.class == value.getClass()) { + + if (type == DBObject.class) { + Object out = JSON.parse(value.toString()); + if (out instanceof DBObject) { + return out; + } else { + throw new InvalidPayloadException(exchange, type); + } + } else if (type == BasicDBList.class) { + Object out = JSON.parse(value.toString()); + if (out instanceof BasicDBList) { + return out; + } else { + throw new InvalidPayloadException(exchange, type); + } + } else if (type == BasicDBObject.class) { + Object out = JSON.parse(value.toString()); + if (out instanceof BasicDBObject) { + return out; + } else { + throw new InvalidPayloadException(exchange, type); + } + } + } + + // okay then fallback and use jackson + if (type == DBObject.class) { + Map<?, ?> m = OBJECT_MAPPER.convertValue(value, Map.class); + return new BasicDBObject(m); + } + + return null; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/54073597/components/camel-mongodb3/src/main/resources/META-INF/services/org/apache/camel/TypeConverter ---------------------------------------------------------------------- diff --git a/components/camel-mongodb3/src/main/resources/META-INF/services/org/apache/camel/TypeConverter b/components/camel-mongodb3/src/main/resources/META-INF/services/org/apache/camel/TypeConverter index c9afc68..794bb11 100644 --- a/components/camel-mongodb3/src/main/resources/META-INF/services/org/apache/camel/TypeConverter +++ b/components/camel-mongodb3/src/main/resources/META-INF/services/org/apache/camel/TypeConverter @@ -15,4 +15,5 @@ # limitations under the License. # -org.apache.camel.component.mongodb3.converters.MongoDbBasicConverters \ No newline at end of file +org.apache.camel.component.mongodb3.converters.MongoDbBasicConverters +org.apache.camel.component.mongodb3.converters.MongoDbFallbackConverter \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/54073597/components/camel-mongodb3/src/test/java/org/apache/camel/component/mongodb3/MongoDbExceptionHandlingTest.java ---------------------------------------------------------------------- diff --git a/components/camel-mongodb3/src/test/java/org/apache/camel/component/mongodb3/MongoDbExceptionHandlingTest.java b/components/camel-mongodb3/src/test/java/org/apache/camel/component/mongodb3/MongoDbExceptionHandlingTest.java index cc0ff2e..352045c 100644 --- a/components/camel-mongodb3/src/test/java/org/apache/camel/component/mongodb3/MongoDbExceptionHandlingTest.java +++ b/components/camel-mongodb3/src/test/java/org/apache/camel/component/mongodb3/MongoDbExceptionHandlingTest.java @@ -16,6 +16,7 @@ */ package org.apache.camel.component.mongodb3; +import com.mongodb.DBObject; import org.apache.camel.builder.RouteBuilder; import org.bson.Document; import org.junit.Test; @@ -38,6 +39,26 @@ public class MongoDbExceptionHandlingTest extends AbstractMongoDbTest { } @Test + public void testInduceParseAndThenOkException() throws Exception { + // Test that the collection has 0 documents in it + assertEquals(0, testCollection.count()); + pumpDataIntoTestCollection(); + + // notice missing quote at the end of Einstein + try { + template.requestBody("direct:findOneByQuery", "{\"scientist\": \"Einstein}"); + fail("Should have thrown an exception"); + } catch (Exception e) { + extractAndAssertCamelMongoDbException(e, null); + } + + // this one is okay + DBObject out = template.requestBody("direct:findOneByQuery", "{\"scientist\": \"Einstein\"}", DBObject.class); + assertNotNull(out); + assertEquals("Einstein", out.get("scientist")); + } + + @Test public void testErroneousDynamicOperation() throws Exception { // Test that the collection has 0 documents in it assertEquals(0, testCollection.count());