apache / camel-k

Apache Camel K is a lightweight integration platform, born on Kubernetes, with serverless superpowers
https://camel.apache.org/camel-k
Apache License 2.0
868 stars 349 forks source link

Rest "contract first" fails with variable in api path #5939

Open hernanDatgDev opened 1 week ago

hernanDatgDev commented 1 week ago

What happened?

There's an issue providing an open-api spec (contract first) when the spec has variables in the paths i.e.

rest().openApi("my-api.json")

my-api.json:

/users: ...
/users/{employeeid}: ...
/users/{employeeid}/location: ...

The api spec is provided via configmap and endpoints without variables can be reached as expected. There is an index out of bounds error when trying to reach endpoint /users/{employeeid} with /users/myid123:

 2024-11-11 23:05:39,689 WARN  [org.apa.cam.com.pla.htt.ver.VertxPlatformHttpConsumer] (vert.x-eventloop-thread-0) Failed handling platform-http endpoint /. Caused by: [java.lang.ArrayIndexOutOfBoundsException - Index 2 out of bounds for length 2]: java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2
[1]     at org.apache.camel.http.base.HttpHelper.evalPlaceholders(HttpHelper.java:170)

What I noticed is that endpoing /users/{employeeid}/location can be reached with /users/myid123/location but the expectation is that there is a header: employeeid = myid123 however the value of the header is actually location. It seems there is an offset when the endpoint is being parsed for variables. The json I return shows the wrong value parsed for employeeId:

{
    "employeeId": "location",
    "location": "unknown"
}

In the HttpHelper.evalPlaceholders() that's throwing the exception, I imagine there might be some misconfiguration on what is considered the "URL path" vs the "consumerPath". I haven't been able to identify exactly where the issue is but I imagine it will be in:

[1]     at org.apache.camel.component.rest.openapi.RestOpenApiProcessor.process(RestOpenApiProcessor.java:131)

📓 NOTE: When using the rest DSL e.g. rest().get("/users/{employeeid}"), the api works as expected with no issues.

Steps to reproduce

  1. Create a basic open-api spec that includes variables in the path e.g. /users/{id}
  2. Create and provide this api spec (contract first) as a configmap in your integration e.g.
    
    // camel-k: resource=configmap:user-api-spec
    ...
    configure() {
        rest().openApi("open-api-spec.yaml");
    ...
    }
3. Attempt to reach your endpoint that contains a variable in the path e.g. `/users/id123`

### Relevant log output

```shell
[1] 2024-11-11 23:05:39,689 WARN  [org.apa.cam.com.pla.htt.ver.VertxPlatformHttpConsumer] (vert.x-eventloop-thread-0) Failed handling platform-http endpoint /. Caused by: [java.lang.ArrayIndexOutOfBoundsException - Index 2 out of bounds for length 2]: java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2
[1]     at org.apache.camel.http.base.HttpHelper.evalPlaceholders(HttpHelper.java:170)
[1]     at org.apache.camel.http.base.HttpHelper.evalPlaceholders(HttpHelper.java:147)
[1]     at org.apache.camel.component.rest.openapi.RestOpenApiProcessor.process(RestOpenApiProcessor.java:131)
...
[1] 2024-11-11 23:05:39,696 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (vert.x-eventloop-thread-0) HTTP Request to /users/myid123 failed, error id: d61930eb-b2ad-476b-b059-dca33681d302-1: java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2
[1]     at org.apache.camel.http.base.HttpHelper.evalPlaceholders(HttpHelper.java:170)
[1]     at org.apache.camel.http.base.HttpHelper.evalPlaceholders(HttpHelper.java:147)
[1]     at org.apache.camel.component.rest.openapi.RestOpenApiProcessor.process(RestOpenApiProcessor.java:131)

Camel K version

v2.5.0

squakez commented 1 week ago

Thanks for reporting. I've done some test and I am not able to reproduce. Would you mind providing a complete failing reproducer? From the exception and the result of your initial investigation it seems more a Camel core bug. You may try the very same route with a local development (ie, via camel run from Camel JBang): in this way we can understand better what part of the system would be requiring a fix.