You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by kl...@apache.org on 2022/05/04 10:56:22 UTC
[camel] 01/01: CAMEL-17956: use registered ObjectMapper when parsing json. Add unit tests showing use of custom ObjectMapper for both parsing and serialization.
This is an automated email from the ASF dual-hosted git repository.
klease pushed a commit to branch CAMEL-17956
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 146f770015cbb48b1bf3c6ccc5953f8ed2c919d7
Author: klease <kl...@cegetel.net>
AuthorDate: Wed May 4 12:47:41 2022 +0200
CAMEL-17956: use registered ObjectMapper when parsing json.
Add unit tests showing use of custom ObjectMapper for both parsing
and serialization.
---
.../org/apache/camel/jsonpath/JsonPathEngine.java | 29 +++++-
.../apache/camel/jsonpath/JsonPathExpression.java | 2 +-
.../apache/camel/jsonpath/CustomObjectMapper.java | 29 ++++++
.../camel/jsonpath/JsonPathCustomMapperTest.java | 102 +++++++++++++++++++++
.../SpringJsonPathCustomReadMapperBeanTest.java | 53 +++++++++++
.../src/test/resources/bignumbers.json | 11 +++
.../SpringJsonPathCustomReadMapperBeanTest.xml | 40 ++++++++
7 files changed, 261 insertions(+), 5 deletions(-)
diff --git a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java
index 6fb4f8c8ff4..92fd05d4cd1 100644
--- a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java
+++ b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java
@@ -24,14 +24,17 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
+import org.apache.camel.CamelContext;
import org.apache.camel.CamelExchangeException;
import org.apache.camel.Exchange;
import org.apache.camel.Expression;
@@ -61,11 +64,11 @@ public class JsonPathEngine {
@Deprecated
public JsonPathEngine(String expression) {
- this(expression, false, false, true, null, null);
+ this(expression, false, false, true, null, null, null);
}
public JsonPathEngine(String expression, boolean writeAsString, boolean suppressExceptions, boolean allowSimple,
- String headerName, Option[] options) {
+ String headerName, Option[] options, CamelContext context) {
this.expression = expression;
this.writeAsString = writeAsString;
this.headerName = headerName;
@@ -74,8 +77,16 @@ public class JsonPathEngine {
if (options != null) {
builder.options(options);
}
- builder.jsonProvider(new JacksonJsonProvider());
- builder.mappingProvider(new JacksonMappingProvider());
+ // Use custom ObjectMapper if provided (CAMEL-17956)
+ ObjectMapper objectMapper = findRegisteredMapper(context);
+ if (objectMapper != null) {
+ builder.jsonProvider(new JacksonJsonProvider(objectMapper));
+ builder.mappingProvider(new JacksonMappingProvider(objectMapper));
+ } else {
+ builder.jsonProvider(new JacksonJsonProvider());
+ builder.mappingProvider(new JacksonMappingProvider());
+ }
+
if (suppressExceptions) {
builder.options(SUPPRESS_EXCEPTIONS);
}
@@ -92,6 +103,16 @@ public class JsonPathEngine {
this.hasSimple = simpleInUse;
}
+ private ObjectMapper findRegisteredMapper(CamelContext context) {
+ if (context != null) {
+ Set<ObjectMapper> mappers = context.getRegistry().findByType(ObjectMapper.class);
+ if (mappers.size() == 1) {
+ return mappers.iterator().next();
+ }
+ }
+ return null;
+ }
+
@SuppressWarnings("unchecked")
public Object read(Exchange exchange) throws Exception {
Object answer;
diff --git a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
index b40c7ce6430..c2cb7df322a 100644
--- a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
+++ b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
@@ -175,7 +175,7 @@ public class JsonPathExpression extends ExpressionAdapter {
LOG.debug("Initializing {} using: {}", predicate ? "predicate" : "expression", exp);
try {
- engine = new JsonPathEngine(exp, writeAsString, suppressExceptions, allowSimple, headerName, options);
+ engine = new JsonPathEngine(exp, writeAsString, suppressExceptions, allowSimple, headerName, options, context);
} catch (Exception e) {
throw new ExpressionIllegalSyntaxException(exp, e);
}
diff --git a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/CustomObjectMapper.java b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/CustomObjectMapper.java
new file mode 100644
index 00000000000..77dc1339bca
--- /dev/null
+++ b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/CustomObjectMapper.java
@@ -0,0 +1,29 @@
+/*
+ * 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.jsonpath;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class CustomObjectMapper extends ObjectMapper {
+
+ public CustomObjectMapper() {
+ super();
+ this.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
+ }
+
+}
diff --git a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathCustomMapperTest.java b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathCustomMapperTest.java
new file mode 100644
index 00000000000..1b462dd36db
--- /dev/null
+++ b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathCustomMapperTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.jsonpath;
+
+import java.io.File;
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.Module;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.spi.Registry;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class JsonPathCustomMapperTest extends CamelTestSupport {
+
+ static class CustomDoubleSerializer extends JsonSerializer<Double> {
+
+ @Override
+ public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+ gen.writeRawValue(String.format("%.6f", value));
+ }
+ }
+
+ static class CustomModule extends SimpleModule {
+ CustomModule() {
+ addSerializer(Double.class, new CustomDoubleSerializer());
+ }
+
+ @Override
+ public String getModuleName() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public int hashCode() {
+ return getClass().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return this == o;
+ }
+ }
+
+ @Override
+ protected void bindToRegistry(Registry registry) throws Exception {
+ ObjectMapper customMapper = new ObjectMapper();
+ Module doubleModule = new CustomModule();
+ customMapper.registerModule(doubleModule);
+ registry.bind("customMapper", customMapper);
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+
+ from("direct:jsonAsString")
+ .split().jsonpathWriteAsString("$")
+ .log("${body}")
+ .to("mock:resultString");
+ }
+ };
+ }
+
+ @Test
+ public void testJsonPathWriteCustomDoubles() throws Exception {
+ // /CAMEL-17956
+ MockEndpoint m = getMockEndpoint("mock:resultString");
+ m.expectedMessageCount(1);
+ template.sendBody("direct:jsonAsString", new File("src/test/resources/bignumbers.json"));
+ Object resultFromMock = m.getReceivedExchanges().get(0).getMessage().getBody();
+ assertTrue(resultFromMock instanceof String);
+ assertTrue(resultFromMock.toString().contains("121002700.0"));
+ assertTrue(resultFromMock.toString().contains("-91000000.0"));
+
+ }
+
+}
diff --git a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/SpringJsonPathCustomReadMapperBeanTest.java b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/SpringJsonPathCustomReadMapperBeanTest.java
new file mode 100644
index 00000000000..7c06d521071
--- /dev/null
+++ b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/SpringJsonPathCustomReadMapperBeanTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.jsonpath;
+
+import java.io.File;
+
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.spring.junit5.CamelSpringTestSupport;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.support.AbstractApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class SpringJsonPathCustomReadMapperBeanTest extends CamelSpringTestSupport {
+
+ @Override
+ protected AbstractApplicationContext createApplicationContext() {
+ return new ClassPathXmlApplicationContext("org/apache/camel/jsonpath/SpringJsonPathCustomReadMapperBeanTest.xml");
+ }
+
+ @Test
+ public void testJsonPathSplitNumbers() throws Exception {
+ // /CAMEL-17956
+ MockEndpoint m = getMockEndpoint("mock:result");
+ m.expectedMessageCount(1);
+ template.requestBody("direct:start", new File("src/test/resources/bignumbers.json"), String.class);
+ Object resultFromMock = m.getReceivedExchanges().get(0).getMessage().getBody();
+ // assertTrue(resultFromMock instanceof Map);
+ // Map<String,Object> resultMap = (Map)resultFromMock;
+ // assertTrue(resultMap.get("principalAmountOnValueDate") instanceof BigDecimal);
+ assertTrue(resultFromMock instanceof String);
+ assertTrue(resultFromMock.toString().contains("121002700.0"));
+ assertTrue(resultFromMock.toString().contains("-91000000.0"));
+ assertMockEndpointsSatisfied();
+
+ }
+
+}
diff --git a/components/camel-jsonpath/src/test/resources/bignumbers.json b/components/camel-jsonpath/src/test/resources/bignumbers.json
new file mode 100644
index 00000000000..f055b5783f2
--- /dev/null
+++ b/components/camel-jsonpath/src/test/resources/bignumbers.json
@@ -0,0 +1,11 @@
+[
+ {
+ "adjustedRate" : 1.23,
+ "collateralQuantityOrNominalAmount": 987.654321,
+ "fixedRate" : -0.62,
+ "floatingRate" : 4.56,
+ "principalAmountOnMaturityDate" : 121002700.0,
+ "principalAmountOnValueDate" : -91000000.0,
+ "spread" : 4.56
+ }
+]
\ No newline at end of file
diff --git a/components/camel-jsonpath/src/test/resources/org/apache/camel/jsonpath/SpringJsonPathCustomReadMapperBeanTest.xml b/components/camel-jsonpath/src/test/resources/org/apache/camel/jsonpath/SpringJsonPathCustomReadMapperBeanTest.xml
new file mode 100644
index 00000000000..352a9b22a4f
--- /dev/null
+++ b/components/camel-jsonpath/src/test/resources/org/apache/camel/jsonpath/SpringJsonPathCustomReadMapperBeanTest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
+ <route>
+ <from uri="direct:start"/>
+ <split>
+ <jsonpath writeAsString="true">$</jsonpath>
+ <to uri="log:line"/>
+ <to uri="mock:result"/>
+
+ </split>
+ </route>
+ </camelContext>
+
+ <bean id="customMapper" class="org.apache.camel.jsonpath.CustomObjectMapper"/>
+
+</beans>
\ No newline at end of file