[
https://issues.apache.org/jira/browse/CAMEL-24986?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen updated CAMEL-24986:
--------------------------------
Fix Version/s: 4.23.0
> camel-rest: a REST producer sends the request when a path parameter has no
> value, with the placeholder still in the uri
> -----------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24986
> URL: https://issues.apache.org/jira/browse/CAMEL-24986
> Project: Camel
> Issue Type: Improvement
> Components: camel-rest-openapi, rest
> Reporter: Claus Ibsen
> Priority: Major
> Fix For: 4.23.0
>
>
> A REST producer sends the request even when a path parameter has no value, so
> the call goes out with the placeholder still in it:
> {noformat}
> org.apache.camel.http.base.HttpOperationFailedException: HTTP operation
> failed invoking
> http://localhost:8080/api/stock/%7Bsku%7D/reserve with statusCode: 404
> {noformat}
> {{%7Bsku%7D}} is {{\{sku\}}}. Nothing says the parameter was not resolved;
> the caller sees a 404 from the server and starts looking at the server.
> h3. Where it comes from
> {{RestProducer.prepareExchange}} resolves each path segment with
> {{resolvePlaceholders}}, which reads a header and falls back to an exchange
> variable:
> {code:java}
> String value = exchange.getMessage().getHeader(key, String.class);
> if (value == null) {
> value = exchange.getVariable(key, String.class);
> }
> if (value != null) {
> res = res.substring(0, startIndex) + value + res.substring(endIndex + 1);
> }
> {code}
> When neither has a value the placeholder is left as it is, and the request is
> sent anyway. {{hasPath}} is set only when at least one segment resolved, so a
> fully unresolved template falls through to the endpoint uri unchanged, and a
> partly resolved one carries the rest into {{REST_HTTP_URI}}.
> h3. What to do
> # *Fail instead of sending it.* After the resolution loop, when the template
> still holds a {{\{name\}}}, throw and say which parameter it is and where the
> value comes from, e.g. "the path parameter \{sku\} of
> /api/stock/\{sku\}/reserve has no value: set a header sku, or an exchange
> variable, before the call". {{prepareUriTemplate=false}} remains the way to
> send a uri with braces on purpose.
> # *Say it before it runs.* The YAML validator knows the OpenAPI specification
> already - {{OpenApiVerbs}} reads it for CAMEL-24844 phase B - so for a
> {{rest-openapi}} producer it can see that {{reserveStock}} needs a {{sku}}
> path parameter and that no step before the call sets that header, and report
> it at write time.
> h3. How often it happens
> Measured on an overnight local-model benchmark (22 examples, 5 passes, 360
> steps): this single mistake produced *2580* of the runtime errors, the most
> of any cause, and appeared in *13 of 15 runs* across the three HTTP examples.
> The model does set the header in the route; the value does not arrive, and
> nothing in the failure says so. A person reading a 404 has the same problem.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)