This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new d19b9ef6aed camel-json-validator: Added options to set DeserializationFeature for ObjectMapper (#12620) d19b9ef6aed is described below commit d19b9ef6aedee3567c10981cafdcfce4b744372b Author: Ivan Mashtak <deralus...@yandex.ru> AuthorDate: Sat Dec 30 11:41:25 2023 +0300 camel-json-validator: Added options to set DeserializationFeature for ObjectMapper (#12620) --- .../camel/catalog/components/json-validator.json | 6 +- .../JsonValidatorEndpointConfigurer.java | 12 ++++ .../JsonValidatorEndpointUriFactory.java | 4 +- .../component/jsonvalidator/json-validator.json | 6 +- .../jsonvalidator/JsonValidatorEndpoint.java | 52 +++++++++++++--- .../ValidatorDeserializationFeaturesTest.java | 69 ++++++++++++++++++++++ 6 files changed, 137 insertions(+), 12 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/json-validator.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/json-validator.json index 5c84e48720f..3b96226b987 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/json-validator.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/json-validator.json @@ -34,7 +34,9 @@ "failOnNullHeader": { "index": 4, "kind": "parameter", "displayName": "Fail On Null Header", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to fail if no header exists when validating against a header." }, "headerName": { "index": 5, "kind": "parameter", "displayName": "Header Name", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To validate against a header instead of the message body." }, "lazyStartProducer": { "index": 6, "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a produc [...] - "errorHandler": { "index": 7, "kind": "parameter", "displayName": "Error Handler", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.jsonvalidator.JsonValidatorErrorHandler", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom ValidatorErrorHandler. The default error handler captures the errors and throws an exception." }, - "uriSchemaLoader": { "index": 8, "kind": "parameter", "displayName": "Uri Schema Loader", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.jsonvalidator.JsonUriSchemaLoader", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom schema loader allowing for adding custom format validation. The default implementation will create a schema loader that tries to determine the schema ver [...] + "disabledDeserializationFeatures": { "index": 7, "kind": "parameter", "displayName": "Disabled Deserialization Features", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Comma-separated list of Jackson DeserializationFeature enum values which will be disabled for parsing exchange body" }, + "enabledDeserializationFeatures": { "index": 8, "kind": "parameter", "displayName": "Enabled Deserialization Features", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Comma-separated list of Jackson DeserializationFeature enum values which will be enabled for parsing exchange body" }, + "errorHandler": { "index": 9, "kind": "parameter", "displayName": "Error Handler", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.jsonvalidator.JsonValidatorErrorHandler", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom ValidatorErrorHandler. The default error handler captures the errors and throws an exception." }, + "uriSchemaLoader": { "index": 10, "kind": "parameter", "displayName": "Uri Schema Loader", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.jsonvalidator.JsonUriSchemaLoader", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom schema loader allowing for adding custom format validation. The default implementation will create a schema loader that tries to determine the schema ve [...] } } diff --git a/components/camel-json-validator/src/generated/java/org/apache/camel/component/jsonvalidator/JsonValidatorEndpointConfigurer.java b/components/camel-json-validator/src/generated/java/org/apache/camel/component/jsonvalidator/JsonValidatorEndpointConfigurer.java index 0ec9b478d09..89d091463ac 100644 --- a/components/camel-json-validator/src/generated/java/org/apache/camel/component/jsonvalidator/JsonValidatorEndpointConfigurer.java +++ b/components/camel-json-validator/src/generated/java/org/apache/camel/component/jsonvalidator/JsonValidatorEndpointConfigurer.java @@ -25,6 +25,10 @@ public class JsonValidatorEndpointConfigurer extends PropertyConfigurerSupport i case "allowContextMapAll": target.setAllowContextMapAll(property(camelContext, boolean.class, value)); return true; case "contentcache": case "contentCache": target.setContentCache(property(camelContext, boolean.class, value)); return true; + case "disableddeserializationfeatures": + case "disabledDeserializationFeatures": target.setDisabledDeserializationFeatures(property(camelContext, java.lang.String.class, value)); return true; + case "enableddeserializationfeatures": + case "enabledDeserializationFeatures": target.setEnabledDeserializationFeatures(property(camelContext, java.lang.String.class, value)); return true; case "errorhandler": case "errorHandler": target.setErrorHandler(property(camelContext, org.apache.camel.component.jsonvalidator.JsonValidatorErrorHandler.class, value)); return true; case "failonnullbody": @@ -48,6 +52,10 @@ public class JsonValidatorEndpointConfigurer extends PropertyConfigurerSupport i case "allowContextMapAll": return boolean.class; case "contentcache": case "contentCache": return boolean.class; + case "disableddeserializationfeatures": + case "disabledDeserializationFeatures": return java.lang.String.class; + case "enableddeserializationfeatures": + case "enabledDeserializationFeatures": return java.lang.String.class; case "errorhandler": case "errorHandler": return org.apache.camel.component.jsonvalidator.JsonValidatorErrorHandler.class; case "failonnullbody": @@ -72,6 +80,10 @@ public class JsonValidatorEndpointConfigurer extends PropertyConfigurerSupport i case "allowContextMapAll": return target.isAllowContextMapAll(); case "contentcache": case "contentCache": return target.isContentCache(); + case "disableddeserializationfeatures": + case "disabledDeserializationFeatures": return target.getDisabledDeserializationFeatures(); + case "enableddeserializationfeatures": + case "enabledDeserializationFeatures": return target.getEnabledDeserializationFeatures(); case "errorhandler": case "errorHandler": return target.getErrorHandler(); case "failonnullbody": diff --git a/components/camel-json-validator/src/generated/java/org/apache/camel/component/jsonvalidator/JsonValidatorEndpointUriFactory.java b/components/camel-json-validator/src/generated/java/org/apache/camel/component/jsonvalidator/JsonValidatorEndpointUriFactory.java index 06a8969dc2e..a2ca62ecda4 100644 --- a/components/camel-json-validator/src/generated/java/org/apache/camel/component/jsonvalidator/JsonValidatorEndpointUriFactory.java +++ b/components/camel-json-validator/src/generated/java/org/apache/camel/component/jsonvalidator/JsonValidatorEndpointUriFactory.java @@ -21,9 +21,11 @@ public class JsonValidatorEndpointUriFactory extends org.apache.camel.support.co private static final Set<String> SECRET_PROPERTY_NAMES; private static final Set<String> MULTI_VALUE_PREFIXES; static { - Set<String> props = new HashSet<>(9); + Set<String> props = new HashSet<>(11); props.add("allowContextMapAll"); props.add("contentCache"); + props.add("disabledDeserializationFeatures"); + props.add("enabledDeserializationFeatures"); props.add("errorHandler"); props.add("failOnNullBody"); props.add("failOnNullHeader"); diff --git a/components/camel-json-validator/src/generated/resources/org/apache/camel/component/jsonvalidator/json-validator.json b/components/camel-json-validator/src/generated/resources/org/apache/camel/component/jsonvalidator/json-validator.json index 5c84e48720f..3b96226b987 100644 --- a/components/camel-json-validator/src/generated/resources/org/apache/camel/component/jsonvalidator/json-validator.json +++ b/components/camel-json-validator/src/generated/resources/org/apache/camel/component/jsonvalidator/json-validator.json @@ -34,7 +34,9 @@ "failOnNullHeader": { "index": 4, "kind": "parameter", "displayName": "Fail On Null Header", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to fail if no header exists when validating against a header." }, "headerName": { "index": 5, "kind": "parameter", "displayName": "Header Name", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To validate against a header instead of the message body." }, "lazyStartProducer": { "index": 6, "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a produc [...] - "errorHandler": { "index": 7, "kind": "parameter", "displayName": "Error Handler", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.jsonvalidator.JsonValidatorErrorHandler", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom ValidatorErrorHandler. The default error handler captures the errors and throws an exception." }, - "uriSchemaLoader": { "index": 8, "kind": "parameter", "displayName": "Uri Schema Loader", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.jsonvalidator.JsonUriSchemaLoader", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom schema loader allowing for adding custom format validation. The default implementation will create a schema loader that tries to determine the schema ver [...] + "disabledDeserializationFeatures": { "index": 7, "kind": "parameter", "displayName": "Disabled Deserialization Features", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Comma-separated list of Jackson DeserializationFeature enum values which will be disabled for parsing exchange body" }, + "enabledDeserializationFeatures": { "index": 8, "kind": "parameter", "displayName": "Enabled Deserialization Features", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Comma-separated list of Jackson DeserializationFeature enum values which will be enabled for parsing exchange body" }, + "errorHandler": { "index": 9, "kind": "parameter", "displayName": "Error Handler", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.jsonvalidator.JsonValidatorErrorHandler", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom ValidatorErrorHandler. The default error handler captures the errors and throws an exception." }, + "uriSchemaLoader": { "index": 10, "kind": "parameter", "displayName": "Uri Schema Loader", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.jsonvalidator.JsonUriSchemaLoader", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom schema loader allowing for adding custom format validation. The default implementation will create a schema loader that tries to determine the schema ve [...] } } diff --git a/components/camel-json-validator/src/main/java/org/apache/camel/component/jsonvalidator/JsonValidatorEndpoint.java b/components/camel-json-validator/src/main/java/org/apache/camel/component/jsonvalidator/JsonValidatorEndpoint.java index 499234ef48c..10df1843271 100644 --- a/components/camel-json-validator/src/main/java/org/apache/camel/component/jsonvalidator/JsonValidatorEndpoint.java +++ b/components/camel-json-validator/src/main/java/org/apache/camel/component/jsonvalidator/JsonValidatorEndpoint.java @@ -19,16 +19,12 @@ package org.apache.camel.component.jsonvalidator; import java.io.InputStream; import java.util.Set; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.networknt.schema.JsonSchema; import com.networknt.schema.ValidationMessage; -import org.apache.camel.Category; -import org.apache.camel.Component; -import org.apache.camel.Exchange; -import org.apache.camel.ExchangePattern; -import org.apache.camel.StreamCache; -import org.apache.camel.ValidationException; +import org.apache.camel.*; import org.apache.camel.api.management.ManagedResource; import org.apache.camel.component.ResourceEndpoint; import org.apache.camel.spi.UriEndpoint; @@ -45,7 +41,7 @@ public class JsonValidatorEndpoint extends ResourceEndpoint { private volatile JsonSchema schema; - private final ObjectMapper mapper = new ObjectMapper(); + private ObjectMapper mapper; @UriParam(defaultValue = "true") private boolean failOnNullBody = true; @@ -59,6 +55,14 @@ public class JsonValidatorEndpoint extends ResourceEndpoint { @UriParam(label = "advanced") private JsonUriSchemaLoader uriSchemaLoader = new DefaultJsonUriSchemaLoader(); + @UriParam(label = "advanced", + description = "Comma-separated list of Jackson DeserializationFeature enum values which will be enabled for parsing exchange body") + private String enabledDeserializationFeatures; + + @UriParam(label = "advanced", + description = "Comma-separated list of Jackson DeserializationFeature enum values which will be disabled for parsing exchange body") + private String disabledDeserializationFeatures; + public JsonValidatorEndpoint(String endpointUri, Component component, String resourceUri) { super(endpointUri, component, resourceUri); } @@ -69,6 +73,24 @@ public class JsonValidatorEndpoint extends ResourceEndpoint { super.clearContentCache(); } + @Override + protected void doInit() throws Exception { + super.doInit(); + mapper = new ObjectMapper(); + if (enabledDeserializationFeatures != null) { + for (var featureName : enabledDeserializationFeatures.split(",")) { + var feature = DeserializationFeature.valueOf(featureName); + mapper.enable(feature); + } + } + if (disabledDeserializationFeatures != null) { + for (var featureName : disabledDeserializationFeatures.split(",")) { + var feature = DeserializationFeature.valueOf(featureName); + mapper.disable(feature); + } + } + } + @Override public ExchangePattern getExchangePattern() { return ExchangePattern.InOut; @@ -249,4 +271,20 @@ public class JsonValidatorEndpoint extends ResourceEndpoint { public void setHeaderName(String headerName) { this.headerName = headerName; } + + public String getEnabledDeserializationFeatures() { + return enabledDeserializationFeatures; + } + + public void setEnabledDeserializationFeatures(String enabledDeserializationFeatures) { + this.enabledDeserializationFeatures = enabledDeserializationFeatures; + } + + public String getDisabledDeserializationFeatures() { + return disabledDeserializationFeatures; + } + + public void setDisabledDeserializationFeatures(String disabledDeserializationFeatures) { + this.disabledDeserializationFeatures = disabledDeserializationFeatures; + } } diff --git a/components/camel-json-validator/src/test/java/org/apache/camel/component/jsonvalidator/ValidatorDeserializationFeaturesTest.java b/components/camel-json-validator/src/test/java/org/apache/camel/component/jsonvalidator/ValidatorDeserializationFeaturesTest.java new file mode 100644 index 00000000000..1fbf6e0fdfd --- /dev/null +++ b/components/camel-json-validator/src/test/java/org/apache/camel/component/jsonvalidator/ValidatorDeserializationFeaturesTest.java @@ -0,0 +1,69 @@ +/* + * 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.jsonvalidator; + +import org.apache.camel.EndpointInject; +import org.apache.camel.RoutesBuilder; +import org.apache.camel.ValidationException; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Test; + +public class ValidatorDeserializationFeaturesTest extends CamelTestSupport { + + @EndpointInject("mock:valid") + protected MockEndpoint validEndpoint; + + @EndpointInject("mock:finally") + protected MockEndpoint finallyEndpoint; + + @EndpointInject("mock:invalid") + protected MockEndpoint invalidEndpoint; + + @Test + public void testInvalidMessage() throws Exception { + validEndpoint.expectedMessageCount(0); + invalidEndpoint.expectedMessageCount(1); + finallyEndpoint.expectedMessageCount(1); + + template.sendBody("direct:start", + "{ \"name\": \"Joe Doe\", \"id\": 1, \"price\": 12.5 }secret"); + + MockEndpoint.assertIsSatisfied(validEndpoint, invalidEndpoint, finallyEndpoint); + } + + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start") + .doTry() + .to("json-validator:org/apache/camel/component/jsonvalidator/schema.json" + + "?enabledDeserializationFeatures=FAIL_ON_TRAILING_TOKENS" + ) + .to("mock:valid") + .doCatch(ValidationException.class) + .to("mock:invalid") + .doFinally() + .to("mock:finally") + .end(); + } + }; + } +}