[ 
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)

Reply via email to