[
https://issues.apache.org/jira/browse/CAMEL-24986?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18118806#comment-18118806
]
Claus Ibsen commented on CAMEL-24986:
-------------------------------------
Merged in main for 4.23.0 (PR #26843): the producer says which path parameter
has no value instead of sending the request with the placeholder in the path
and leaving a 404 to explain it.
h3. A correction to this issue's premise
The description says this mistake produced 2580 runtime errors in an overnight
benchmark. It appeared that many times in the logs, but the path parameter
*does* resolve correctly. Tested end to end against a listener rather than read
from the source:
{noformat}
POST /api/stock/CAMEL-MUG/reserve HTTP/1.1
{noformat}
That is {{rest-openapi}} with {{operationId: reserveStock}} against a
specification whose path is {{/stock/\{sku\}/reserve}}, with {{sku}} set as a
header. {{RestOpenApiEndpoint.resolveUri}} leaves {{\{sku\}}} for the {{rest:}}
endpoint it builds and {{RestProducer.resolvePlaceholders}} substitutes it from
the header. There is no defect in that path.
The 2580 came from a model's intermediate route versions during its edit loop:
{{camel-run.out}} accumulates across every dev mode reload within an example,
so a broken draft keeps logging until the file is fixed. Those are transient
authoring states, not one systemic failure.
The merged change therefore does something narrower than this issue claimed: it
explains an unresolved placeholder when there is one, which is what the
authoring loop needed and never got.
The second item, saying it before the route runs from the OpenAPI
specification, is moved to its own issue: it belongs to the YAML validator
rather than to camel-rest, and it is the part that prevents the mistake rather
than explaining it.
> 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
>
> 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)