This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch binding3 in repository https://gitbox.apache.org/repos/asf/camel.git
commit 3c235f755619ecc75b35235096d30cbf8af7eefc Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Thu Apr 4 08:09:24 2024 +0200 CAMEL-20557: Rest DSL to use openapi spec directly --- ...mHttpRestOpenApiConsumerRestDslBindingTest.java | 8 +++---- .../rest/openapi/RestOpenApiComponent.java | 12 ++++++---- .../org/apache/camel/spi/RestConfiguration.java | 13 +++++++++++ .../camel/impl/RestConfigurationConfigurer.java | 6 +++++ .../apache/camel/model/rest/restConfiguration.json | 27 +++++++++++----------- .../model/rest/RestConfigurationDefinition.java | 27 ++++++++++++++++++++++ .../apache/camel/model/rest/RestDefinition.java | 13 ++++++----- .../camel/reifier/rest/RestBindingReifier.java | 1 + .../RestConfigurationPropertiesConfigurer.java | 6 +++++ .../camel-main-configuration-metadata.json | 1 + core/camel-main/src/main/docs/main.adoc | 3 ++- .../camel/main/RestConfigurationProperties.java | 9 ++++++++ .../processor/RestBindingConfiguration.java | 9 ++++++++ .../java/org/apache/camel/xml/in/ModelParser.java | 1 + .../java/org/apache/camel/xml/out/ModelWriter.java | 1 + .../org/apache/camel/yaml/out/ModelWriter.java | 1 + 16 files changed, 109 insertions(+), 29 deletions(-) diff --git a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerRestDslBindingTest.java b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerRestDslBindingTest.java index 208f77982eb..454a7e6cec9 100644 --- a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerRestDslBindingTest.java +++ b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerRestDslBindingTest.java @@ -73,11 +73,9 @@ public class PlatformHttpRestOpenApiConsumerRestDslBindingTest { context.addRoutes(new RouteBuilder() { @Override public void configure() { - // TODO: make it easy to set binding package name in rest configuration - context.getCamelContextExtension() - .setBasePackageScan("org.apache.camel.component.platform.http.vertx.model"); - - restConfiguration().bindingMode(RestBindingMode.json); + // turn on json binding and scan for POJO classes in the model package + restConfiguration().bindingMode(RestBindingMode.json) + .bindingPackageScan("org.apache.camel.component.platform.http.vertx.model"); rest().openApi().specification("openapi-v3.json").missingOperation("ignore"); diff --git a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiComponent.java b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiComponent.java index c5d5f85e123..2a4cd9ce10f 100644 --- a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiComponent.java +++ b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiComponent.java @@ -171,10 +171,14 @@ public final class RestOpenApiComponent extends DefaultComponent implements SSLC protected void doInit() throws Exception { super.doInit(); - // use package scan for binding model classes - String current = getCamelContext().getCamelContextExtension().getBasePackageScan(); - if (current != null && bindingPackageScan == null) { - bindingPackageScan = current; + if (bindingPackageScan == null) { + // prioritize use rest configuration + String base = getCamelContext().getRestConfiguration().getBindingPackageScan(); + if (base == null) { + // over general base package from camel context + base = getCamelContext().getCamelContextExtension().getBasePackageScan(); + } + bindingPackageScan = base; } } diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java b/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java index ac2c5fe4950..bda68605e6e 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java @@ -63,6 +63,7 @@ public class RestConfiguration { private boolean apiVendorExtension; private RestHostNameResolver hostNameResolver = RestHostNameResolver.allLocalIp; private RestBindingMode bindingMode = RestBindingMode.off; + private String bindingPackageScan; private boolean skipBindingOnErrorCode = true; private boolean clientRequestValidation; private boolean inlineRoutes = true; @@ -362,6 +363,18 @@ public class RestConfiguration { this.bindingMode = RestBindingMode.valueOf(bindingMode); } + public String getBindingPackageScan() { + return bindingPackageScan; + } + + /** + * Package name to use as base (offset) for classpath scanning of POJO classes are located when using binding mode is enabled for JSon or XML. + * Multiple package names can be separated by comma. + */ + public void setBindingPackageScan(String bindingPackageScan) { + this.bindingPackageScan = bindingPackageScan; + } + /** * Whether to skip binding output if there is a custom HTTP error code, and instead use the response body as-is. * <p/> diff --git a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/RestConfigurationConfigurer.java b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/RestConfigurationConfigurer.java index 7b6bccedec5..2e76fd7cb9e 100644 --- a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/RestConfigurationConfigurer.java +++ b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/RestConfigurationConfigurer.java @@ -35,6 +35,8 @@ public class RestConfigurationConfigurer extends org.apache.camel.support.compon case "apiVendorExtension": target.setApiVendorExtension(property(camelContext, boolean.class, value)); return true; case "bindingmode": case "bindingMode": target.setBindingMode(property(camelContext, java.lang.String.class, value)); return true; + case "bindingpackagescan": + case "bindingPackageScan": target.setBindingPackageScan(property(camelContext, java.lang.String.class, value)); return true; case "clientrequestvalidation": case "clientRequestValidation": target.setClientRequestValidation(property(camelContext, boolean.class, value)); return true; case "component": target.setComponent(property(camelContext, java.lang.String.class, value)); return true; @@ -94,6 +96,8 @@ public class RestConfigurationConfigurer extends org.apache.camel.support.compon case "apiVendorExtension": return boolean.class; case "bindingmode": case "bindingMode": return java.lang.String.class; + case "bindingpackagescan": + case "bindingPackageScan": return java.lang.String.class; case "clientrequestvalidation": case "clientRequestValidation": return boolean.class; case "component": return java.lang.String.class; @@ -154,6 +158,8 @@ public class RestConfigurationConfigurer extends org.apache.camel.support.compon case "apiVendorExtension": return target.isApiVendorExtension(); case "bindingmode": case "bindingMode": return target.getBindingMode(); + case "bindingpackagescan": + case "bindingPackageScan": return target.getBindingPackageScan(); case "clientrequestvalidation": case "clientRequestValidation": return target.isClientRequestValidation(); case "component": return target.getComponent(); diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/restConfiguration.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/restConfiguration.json index d72d7945fc5..60f460e2f1d 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/restConfiguration.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/restConfiguration.json @@ -27,18 +27,19 @@ "apiVendorExtension": { "index": 12, "kind": "attribute", "displayName": "Api Vendor Extension", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether vendor extension is enabled in the Rest APIs. If enabled then Camel will include additional information as vendor extension (eg keys starting with x-) such as route ids, class names etc [...] "hostNameResolver": { "index": 13, "kind": "attribute", "displayName": "Host Name Resolver", "label": "consumer,advanced", "required": false, "type": "enum", "javaType": "org.apache.camel.model.rest.RestHostNameResolver", "enum": [ "allLocalIp", "localHostName", "localIp" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "allLocalIp", "description": "If no hostname has been explicit configured, then this resolver is used to compute the hostname the REST ser [...] "bindingMode": { "index": 14, "kind": "attribute", "displayName": "Binding Mode", "required": false, "type": "enum", "javaType": "org.apache.camel.model.rest.RestBindingMode", "enum": [ "off", "auto", "json", "xml", "json_xml" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "off", "description": "Sets the binding mode to use. The default value is off" }, - "skipBindingOnErrorCode": { "index": 15, "kind": "attribute", "displayName": "Skip Binding On Error Code", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to skip binding on output if there is a custom HTTP error code header. This allows to build custom error messages that do not bind to json \/ xml etc, as success messages otherwise wil [...] - "clientRequestValidation": { "index": 16, "kind": "attribute", "displayName": "Client Request Validation", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to enable validation of the client request to check: 1) Content-Type header matches what the Rest DSL consumes; returns HTTP Status 415 if validation error. 2) Accept header m [...] - "enableCORS": { "index": 17, "kind": "attribute", "displayName": "Enable CORS", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to enable CORS headers in the HTTP response. The default value is false." }, - "enableNoContentResponse": { "index": 18, "kind": "attribute", "displayName": "Enable No Content Response", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to return HTTP 204 with an empty body when a response contains an empty JSON object or XML root object. The default value is false." }, - "inlineRoutes": { "index": 19, "kind": "attribute", "displayName": "Inline Routes", "label": "consumer", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Inline routes in rest-dsl which are linked using direct endpoints. Each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from res [...] - "jsonDataFormat": { "index": 20, "kind": "attribute", "displayName": "Json Data Format", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of specific json data format to use. By default jackson will be used. Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance." }, - "xmlDataFormat": { "index": 21, "kind": "attribute", "displayName": "Xml Data Format", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of specific XML data format to use. By default jaxb will be used. Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance." }, - "componentProperty": { "index": 22, "kind": "element", "displayName": "Component Property", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure as many additional properties for the rest component in use." }, - "endpointProperty": { "index": 23, "kind": "element", "displayName": "Endpoint Property", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure as many additional properties for the rest endpoint in use." }, - "consumerProperty": { "index": 24, "kind": "element", "displayName": "Consumer Property", "label": "consumer,advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure as many additional properties for the rest consumer in use." }, - "dataFormatProperty": { "index": 25, "kind": "element", "displayName": "Data Format Property", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure as many additional properties for the data formats in use. For example set property prettyPrint to true to have json outputted in pretty mode. The properties ca [...] - "apiProperty": { "index": 26, "kind": "element", "displayName": "Api Property", "label": "consumer,advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure as many additional properties for the api documentation. For example set property api.title to my cool stuff" }, - "corsHeaders": { "index": 27, "kind": "element", "displayName": "Cors Headers", "label": "consumer,advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure custom CORS headers." } + "bindingPackageScan": { "index": 15, "kind": "attribute", "displayName": "Binding Package Scan", "label": "consumer,advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Package name to use as base (offset) for classpath scanning of POJO classes are located when using binding mode is enabled for JSon or XML. Multiple package names can be separated by comma." }, + "skipBindingOnErrorCode": { "index": 16, "kind": "attribute", "displayName": "Skip Binding On Error Code", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to skip binding on output if there is a custom HTTP error code header. This allows to build custom error messages that do not bind to json \/ xml etc, as success messages otherwise wil [...] + "clientRequestValidation": { "index": 17, "kind": "attribute", "displayName": "Client Request Validation", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to enable validation of the client request to check: 1) Content-Type header matches what the Rest DSL consumes; returns HTTP Status 415 if validation error. 2) Accept header m [...] + "enableCORS": { "index": 18, "kind": "attribute", "displayName": "Enable CORS", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to enable CORS headers in the HTTP response. The default value is false." }, + "enableNoContentResponse": { "index": 19, "kind": "attribute", "displayName": "Enable No Content Response", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to return HTTP 204 with an empty body when a response contains an empty JSON object or XML root object. The default value is false." }, + "inlineRoutes": { "index": 20, "kind": "attribute", "displayName": "Inline Routes", "label": "consumer", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Inline routes in rest-dsl which are linked using direct endpoints. Each service in Rest DSL is an individual route, meaning that you would have at least two routes per service (rest-dsl, and the route linked from res [...] + "jsonDataFormat": { "index": 21, "kind": "attribute", "displayName": "Json Data Format", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of specific json data format to use. By default jackson will be used. Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance." }, + "xmlDataFormat": { "index": 22, "kind": "attribute", "displayName": "Xml Data Format", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of specific XML data format to use. By default jaxb will be used. Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance." }, + "componentProperty": { "index": 23, "kind": "element", "displayName": "Component Property", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure as many additional properties for the rest component in use." }, + "endpointProperty": { "index": 24, "kind": "element", "displayName": "Endpoint Property", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure as many additional properties for the rest endpoint in use." }, + "consumerProperty": { "index": 25, "kind": "element", "displayName": "Consumer Property", "label": "consumer,advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure as many additional properties for the rest consumer in use." }, + "dataFormatProperty": { "index": 26, "kind": "element", "displayName": "Data Format Property", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure as many additional properties for the data formats in use. For example set property prettyPrint to true to have json outputted in pretty mode. The properties ca [...] + "apiProperty": { "index": 27, "kind": "element", "displayName": "Api Property", "label": "consumer,advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure as many additional properties for the api documentation. For example set property api.title to my cool stuff" }, + "corsHeaders": { "index": 28, "kind": "element", "displayName": "Cors Headers", "label": "consumer,advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to configure custom CORS headers." } } } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java index d770f6cae1a..3186fb5a383 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java @@ -83,6 +83,9 @@ public class RestConfigurationDefinition { @Metadata(defaultValue = "off", enums = "off,auto,json,xml,json_xml") private RestBindingMode bindingMode; @XmlAttribute + @Metadata(label = "consumer,advanced") + private String bindingPackageScan; + @XmlAttribute @Metadata(label = "advanced", javaType = "java.lang.Boolean", defaultValue = "false") private String skipBindingOnErrorCode; @XmlAttribute @@ -313,6 +316,18 @@ public class RestConfigurationDefinition { this.bindingMode = bindingMode; } + public String getBindingPackageScan() { + return bindingPackageScan; + } + + /** + * Package name to use as base (offset) for classpath scanning of POJO classes are located when using binding mode is enabled for JSon or XML. + * Multiple package names can be separated by comma. + */ + public void setBindingPackageScan(String bindingPackageScan) { + this.bindingPackageScan = bindingPackageScan; + } + public String getSkipBindingOnErrorCode() { return skipBindingOnErrorCode; } @@ -658,6 +673,15 @@ public class RestConfigurationDefinition { return this; } + /** + * Package name to use as base (offset) for classpath scanning of POJO classes are located when using binding mode is enabled for JSon or XML. + * Multiple package names can be separated by comma. + */ + public RestConfigurationDefinition bindingPackageScan(String bindingPackageScan) { + setBindingPackageScan(bindingPackageScan); + return this; + } + /** * To specify whether to skip binding output if there is a custom HTTP error code */ @@ -956,6 +980,9 @@ public class RestConfigurationDefinition { if (bindingMode != null) { target.setBindingMode(bindingMode.name()); } + if (bindingPackageScan != null) { + target.setBindingPackageScan(bindingPackageScan); + } if (skipBindingOnErrorCode != null) { target.setSkipBindingOnErrorCode(CamelContextHelper.parseBoolean(context, skipBindingOnErrorCode)); } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java index 427f8136202..fa549a46a8f 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java @@ -997,6 +997,7 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition> binding.setConsumes("application/json;application/xml"); binding.setProduces("application/json;application/xml"); } + binding.setBindingMode(mode); binding.setSkipBindingOnErrorCode(getSkipBindingOnErrorCode()); binding.setClientRequestValidation(getClientRequestValidation()); binding.setEnableCORS(getEnableCORS()); @@ -1006,24 +1007,24 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition> // append options Map<String, Object> options = new HashMap<>(); if (binding.getConsumes() != null) { - options.put("consumes", binding.getConsumes()); + options.put("consumes", parseText(camelContext, binding.getConsumes())); } if (binding.getProduces() != null) { - options.put("produces", binding.getProduces()); + options.put("produces", parseText(camelContext, binding.getProduces())); } if (getClientRequestValidation() != null) { - options.put("clientRequestValidation", getClientRequestValidation()); + options.put("clientRequestValidation", parseBoolean(camelContext, getClientRequestValidation())); } else if (clientValidation) { options.put("clientRequestValidation", "true"); } if (openApi.getMissingOperation() != null) { - options.put("missingOperation", openApi.getMissingOperation()); + options.put("missingOperation", parseText(camelContext, openApi.getMissingOperation())); } if (openApi.getMockIncludePattern() != null) { - options.put("mockIncludePattern", openApi.getMockIncludePattern()); + options.put("mockIncludePattern", parseText(camelContext, openApi.getMockIncludePattern())); } if (openApi.getApiContextPath() != null) { - options.put("apiContextPath", openApi.getApiContextPath()); + options.put("apiContextPath", parseText(camelContext, openApi.getApiContextPath())); } // include optional description diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/rest/RestBindingReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/rest/RestBindingReifier.java index 67f872abec8..6e3f7fa08f4 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/rest/RestBindingReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/rest/RestBindingReifier.java @@ -45,6 +45,7 @@ public class RestBindingReifier extends AbstractReifier { mode = parse(RestBindingMode.class, definition.getBindingMode()).name(); } rbc.setBindingMode(mode); + rbc.setBindingPackageScan(config.getBindingPackageScan()); boolean cors = config.isEnableCORS(); if (definition.getEnableCORS() != null) { cors = parseBoolean(definition.getEnableCORS(), false); diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/RestConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/RestConfigurationPropertiesConfigurer.java index 03d56421c17..41c79ffb94e 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/RestConfigurationPropertiesConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/RestConfigurationPropertiesConfigurer.java @@ -35,6 +35,8 @@ public class RestConfigurationPropertiesConfigurer extends org.apache.camel.supp case "apiVendorExtension": target.setApiVendorExtension(property(camelContext, boolean.class, value)); return true; case "bindingmode": case "bindingMode": target.setBindingMode(property(camelContext, java.lang.String.class, value)); return true; + case "bindingpackagescan": + case "bindingPackageScan": target.setBindingPackageScan(property(camelContext, java.lang.String.class, value)); return true; case "clientrequestvalidation": case "clientRequestValidation": target.setClientRequestValidation(property(camelContext, boolean.class, value)); return true; case "component": target.setComponent(property(camelContext, java.lang.String.class, value)); return true; @@ -94,6 +96,8 @@ public class RestConfigurationPropertiesConfigurer extends org.apache.camel.supp case "apiVendorExtension": return boolean.class; case "bindingmode": case "bindingMode": return java.lang.String.class; + case "bindingpackagescan": + case "bindingPackageScan": return java.lang.String.class; case "clientrequestvalidation": case "clientRequestValidation": return boolean.class; case "component": return java.lang.String.class; @@ -154,6 +158,8 @@ public class RestConfigurationPropertiesConfigurer extends org.apache.camel.supp case "apiVendorExtension": return target.isApiVendorExtension(); case "bindingmode": case "bindingMode": return target.getBindingMode(); + case "bindingpackagescan": + case "bindingPackageScan": return target.getBindingPackageScan(); case "clientrequestvalidation": case "clientRequestValidation": return target.isClientRequestValidation(); case "component": return target.getComponent(); diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json index 942ec07472f..6a5e64eabbf 100644 --- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json +++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json @@ -216,6 +216,7 @@ { "name": "camel.rest.apiProperties", "description": "Sets additional options on api level", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "object", "javaType": "java.util.Map" }, { "name": "camel.rest.apiVendorExtension", "description": "Whether vendor extension is enabled in the Rest APIs. If enabled then Camel will include additional information as vendor extension (eg keys starting with x-) such as route ids, class names etc. Not all 3rd party API gateways and tools supports vendor-extensions when importing your API docs.", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "boolean", "javaType": "boolean", "defaultValue": "false" }, { "name": "camel.rest.bindingMode", "description": "Sets the binding mode to be used by the REST consumer", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "object", "javaType": "org.apache.camel.spi.RestBindingMode", "defaultValue": "RestBindingMode.off", "enum": [ "auto", "off", "json", "xml", "json_xml" ] }, + { "name": "camel.rest.bindingPackageScan", "description": "Package name to use as base (offset) for classpath scanning of POJO classes are located when using binding mode is enabled for JSon or XML. Multiple package names can be separated by comma.", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "string", "javaType": "java.lang.String" }, { "name": "camel.rest.clientRequestValidation", "description": "Whether to enable validation of the client request to check: 1) Content-Type header matches what the Rest DSL consumes; returns HTTP Status 415 if validation error. 2) Accept header matches what the Rest DSL produces; returns HTTP Status 406 if validation error. 3) Missing required data (query parameters, HTTP headers, body); returns HTTP Status 400 if validation error. 4) Parsing error of the message body (JSon, XML or [...] { "name": "camel.rest.component", "description": "Sets the name of the Camel component to use as the REST consumer", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "string", "javaType": "java.lang.String" }, { "name": "camel.rest.componentProperties", "description": "Sets additional options on component level", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": "object", "javaType": "java.util.Map" }, diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc index 2f1bf56bfa1..9030646a5de 100644 --- a/core/camel-main/src/main/docs/main.adoc +++ b/core/camel-main/src/main/docs/main.adoc @@ -282,7 +282,7 @@ The camel.health supports 8 options, which are listed below. === Camel Rest-DSL configurations -The camel.rest supports 28 options, which are listed below. +The camel.rest supports 29 options, which are listed below. [width="100%",cols="2,5,^1,2",options="header"] |=== @@ -294,6 +294,7 @@ The camel.rest supports 28 options, which are listed below. | *camel.rest.apiProperties* | Sets additional options on api level | | Map | *camel.rest.apiVendorExtension* | Whether vendor extension is enabled in the Rest APIs. If enabled then Camel will include additional information as vendor extension (eg keys starting with x-) such as route ids, class names etc. Not all 3rd party API gateways and tools supports vendor-extensions when importing your API docs. | false | boolean | *camel.rest.bindingMode* | Sets the binding mode to be used by the REST consumer | RestBindingMode.off | RestBindingMode +| *camel.rest.bindingPackageScan* | Package name to use as base (offset) for classpath scanning of POJO classes are located when using binding mode is enabled for JSon or XML. Multiple package names can be separated by comma. | | String | *camel.rest.clientRequest{zwsp}Validation* | Whether to enable validation of the client request to check: 1) Content-Type header matches what the Rest DSL consumes; returns HTTP Status 415 if validation error. 2) Accept header matches what the Rest DSL produces; returns HTTP Status 406 if validation error. 3) Missing required data (query parameters, HTTP headers, body); returns HTTP Status 400 if validation error. 4) Parsing error of the message body (JSon, XML or Auto binding mode mus [...] | *camel.rest.component* | Sets the name of the Camel component to use as the REST consumer | | String | *camel.rest.componentProperties* | Sets additional options on component level | | Map diff --git a/core/camel-main/src/main/java/org/apache/camel/main/RestConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/RestConfigurationProperties.java index a39fb09e790..126d1fcbf02 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/RestConfigurationProperties.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/RestConfigurationProperties.java @@ -212,6 +212,15 @@ public class RestConfigurationProperties extends RestConfiguration implements Bo return this; } + /** + * Package name to use as base (offset) for classpath scanning of POJO classes are located when using binding mode is enabled for JSon or XML. + * Multiple package names can be separated by comma. + */ + public RestConfigurationProperties withBindingPackageScan(String bindingPackageScan) { + setBindingPackageScan(bindingPackageScan); + return this; + } + /** * Whether to skip binding on output if there is a custom HTTP error code header. This allows to build custom error * messages that do not bind to json / xml etc, as success messages otherwise will do. diff --git a/core/camel-support/src/main/java/org/apache/camel/support/processor/RestBindingConfiguration.java b/core/camel-support/src/main/java/org/apache/camel/support/processor/RestBindingConfiguration.java index 383d33a3a04..95a4b1ea5e0 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/processor/RestBindingConfiguration.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/processor/RestBindingConfiguration.java @@ -27,6 +27,7 @@ public class RestBindingConfiguration { private String consumes; private String produces; private String bindingMode; + private String bindingPackageScan; private boolean skipBindingOnErrorCode; private boolean clientRequestValidation; private boolean enableCORS; @@ -65,6 +66,14 @@ public class RestBindingConfiguration { this.bindingMode = bindingMode; } + public String getBindingPackageScan() { + return bindingPackageScan; + } + + public void setBindingPackageScan(String bindingPackageScan) { + this.bindingPackageScan = bindingPackageScan; + } + public boolean isSkipBindingOnErrorCode() { return skipBindingOnErrorCode; } diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java index aaefc3d2747..d8807a60ffa 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java @@ -1752,6 +1752,7 @@ public class ModelParser extends BaseParser { case "apiHost": def.setApiHost(val); break; case "apiVendorExtension": def.setApiVendorExtension(val); break; case "bindingMode": def.setBindingMode(RestBindingMode.valueOf(val)); break; + case "bindingPackageScan": def.setBindingPackageScan(val); break; case "clientRequestValidation": def.setClientRequestValidation(val); break; case "component": def.setComponent(val); break; case "contextPath": def.setContextPath(val); break; diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java index b2d94894bf5..eb9433c08bb 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java @@ -4541,6 +4541,7 @@ public class ModelWriter extends BaseWriter { doWriteAttribute("host", def.getHost()); doWriteAttribute("producerComponent", def.getProducerComponent()); doWriteAttribute("enableCORS", def.getEnableCORS()); + doWriteAttribute("bindingPackageScan", def.getBindingPackageScan()); doWriteAttribute("useXForwardHeaders", def.getUseXForwardHeaders()); doWriteAttribute("apiHost", def.getApiHost()); doWriteAttribute("contextPath", def.getContextPath()); diff --git a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java index eecb2246f2d..f4d114a2d51 100644 --- a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java +++ b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java @@ -4541,6 +4541,7 @@ public class ModelWriter extends BaseWriter { doWriteAttribute("host", def.getHost()); doWriteAttribute("producerComponent", def.getProducerComponent()); doWriteAttribute("enableCORS", def.getEnableCORS()); + doWriteAttribute("bindingPackageScan", def.getBindingPackageScan()); doWriteAttribute("useXForwardHeaders", def.getUseXForwardHeaders()); doWriteAttribute("apiHost", def.getApiHost()); doWriteAttribute("contextPath", def.getContextPath());