From 90847050e1f9b5d02c548090e2c0bc9984ce31fc Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Thu, 7 Mar 2024 12:08:47 +0100 Subject: [PATCH] CAMEL-20533: camel-rest - Binding mode json or xml should automatically set consumes/produces on the rest endpoint according to the binding mode. --- .../camel/component/rest/RestEndpoint.java | 4 +- .../camel/model/rest/RestDefinition.java | 49 +++++++++++++------ .../modules/ROOT/pages/rest-dsl.adoc | 12 +++-- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/components/camel-rest/src/main/java/org/apache/camel/component/rest/RestEndpoint.java b/components/camel-rest/src/main/java/org/apache/camel/component/rest/RestEndpoint.java index 064232a1f7c54..b2aa8f87b79b7 100644 --- a/components/camel-rest/src/main/java/org/apache/camel/component/rest/RestEndpoint.java +++ b/components/camel-rest/src/main/java/org/apache/camel/component/rest/RestEndpoint.java @@ -588,8 +588,8 @@ public Consumer createConsumer(Processor processor) throws Exception { getUriTemplate(), getConsumes(), getProduces(), config, getParameters()); configureConsumer(consumer); - // add to rest registry so we can keep track of them, we will remove from the registry when the consumer is removed - // the rest registry will automatic keep track when the consumer is removed, + // add to rest registry, so we can keep track of them, we will remove from the registry when the consumer is removed + // the rest registry will automatically keep track when the consumer is removed, // and un-register the REST service from the registry getCamelContext().getRestRegistry().addRestService(consumer, url, baseUrl, getPath(), getUriTemplate(), getMethod(), getConsumes(), getProduces(), getInType(), getOutType(), getRouteId(), getDescription()); 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 0f82d3d3bb5f5..a2ebaa6404ef3 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 @@ -909,6 +909,11 @@ private void addRouteDefinition( binding.setOutType(parseText(camelContext, verb.getOutType())); binding.setOutTypeClass(verb.getOutTypeClass()); // verb takes precedence over configuration on rest + if (verb.getBindingMode() != null) { + binding.setBindingMode(parseText(camelContext, verb.getBindingMode())); + } else { + binding.setBindingMode(getBindingMode()); + } if (verb.getConsumes() != null) { binding.setConsumes(parseText(camelContext, verb.getConsumes())); } else { @@ -919,10 +924,31 @@ private void addRouteDefinition( } else { binding.setProduces(getProduces()); } - if (verb.getBindingMode() != null) { - binding.setBindingMode(parseText(camelContext, verb.getBindingMode())); - } else { - binding.setBindingMode(getBindingMode()); + if (binding.getType() != null || binding.getOutType() != null && binding.getBindingMode() != null) { + // okay we have binding mode and in/out type defined - then we can infer consume/produces + String mode = binding.getBindingMode(); + if ("json".equals(mode)) { + if (binding.getConsumes() == null && binding.getType() != null) { + binding.setConsumes("application/json"); + } + if (binding.getProduces() == null && binding.getOutType() != null) { + binding.setProduces("application/json"); + } + } else if ("xml".equals(mode)) { + if (binding.getConsumes() == null && binding.getType() != null) { + binding.setConsumes("application/xml"); + } + if (binding.getProduces() == null && binding.getOutType() != null) { + binding.setProduces("application/xml"); + } + } else if ("json_xml".equals(mode)) { + if (binding.getConsumes() == null && binding.getType() != null) { + binding.setConsumes("application/json;application/xml"); + } + if (binding.getProduces() == null && binding.getOutType() != null) { + binding.setProduces("application/json;application/xml"); + } + } } if (verb.getSkipBindingOnErrorCode() != null) { binding.setSkipBindingOnErrorCode(parseText(camelContext, verb.getSkipBindingOnErrorCode())); @@ -968,18 +994,12 @@ private void addRouteDefinition( // append options Map options = new HashMap<>(); - // verb takes precedence over configuration on rest - if (verb.getConsumes() != null) { - options.put("consumes", parseText(camelContext, verb.getConsumes())); - } else if (getConsumes() != null) { - options.put("consumes", getConsumes()); + if (binding.getConsumes() != null) { + options.put("consumes", binding.getConsumes()); } - if (verb.getProduces() != null) { - options.put("produces", parseText(camelContext, verb.getProduces())); - } else if (getProduces() != null) { - options.put("produces", getProduces()); + if (binding.getProduces() != null) { + options.put("produces", binding.getProduces()); } - // append optional type binding information String inType = binding.getType(); if (inType != null) { @@ -989,7 +1009,6 @@ private void addRouteDefinition( if (outType != null) { options.put("outType", outType); } - if (component != null && !component.isEmpty()) { options.put("consumerComponentName", component); } diff --git a/docs/user-manual/modules/ROOT/pages/rest-dsl.adoc b/docs/user-manual/modules/ROOT/pages/rest-dsl.adoc index a32e1ec28a03a..da30ec0b68a5a 100644 --- a/docs/user-manual/modules/ROOT/pages/rest-dsl.adoc +++ b/docs/user-manual/modules/ROOT/pages/rest-dsl.adoc @@ -295,13 +295,13 @@ not enabled. |json |Binding to/from json is enabled, and requires a json capable data format on the classpath. By default Camel will use `jackson` as the -data format. See the INFO box below for more details. +data format. |xml |Binding to/from xml is enabled, and requires `camel-jaxb` on the -classpath. See the INFO box below for more details. +classpath. |json_xml |Binding to/from json and xml is enabled and requires both data formats to -be on the classpath. See the INFO box below for more details. +be on the classpath. |=== When using camel-jaxb for xml bindings, then @@ -372,7 +372,11 @@ json_xml |JSON |=== When using binding you must also configure what POJO type to map to. -This is mandatory for incoming messages, and optional for outgoing. +This is mandatory for incoming messages, and optional for outgoing. + +NOTE: When using binding mode `json`, `xml` or `json_xml` then Camel will automatically set `consumers` and `produces` +on the rest endpoint (according to the mode), if not already explicit configured. For example with binding mode `json` +and setting the outType as `UserPojo` then Camel will define this rest endpoint as producing `application/json`. For example to map from xml/json to a pojo class `UserPojo` you do this in Java DSL as shown below: