microcks / microcks-testcontainers-java

Java lib for Testcontainers that enables embedding Microcks into your JUnit tests with lightweight, throwaway instance thanks to containers.
https://microcks.io
Apache License 2.0
18 stars 3 forks source link

Using Microcks API to add header constraints to OpenAPI-based API mocks #51

Open frademacher opened 2 weeks ago

frademacher commented 2 weeks ago

Describe the bug

Hi all. I'm using Microcks Testcontainers Java (0.2.8) to mock an API based on an OpenAPI specification provided by an external party. The external implementation of this API relies on API keys to secure access to certain operations. When mocking this API, I'd also like to mock these API keys by requiring clients that call a mock operation to also send fake API keys.

Since the API keys are expected to be provided as HTTP header key-value pairs, I tried to specify Microcks header constraints for their mocking. If I understood Microcks' documentation correctly, there is currently no means (like x-microcks) to embed header constraints in OpenAPI specs that are to be imported into a Microcks Testcontainer instance. I therefore tried to rely on Microcks own API and more specifically its Override Service Operation endpoint.

However, when calling this endpoint, I'm always receiving a 403 Forbidden response, even though I understand Microcks Testcontainer Java build to disable both authentication and authorization. The former circumstance I checked using the Get Authentification Configuration of Microcks' API, which indeed returns "enabled": false as part of its JSON response.

Expected behavior

Assuming that the provided service ID, operation name, and body are correct, Microcks Override Service Operation endpoint should not emit a 403 Forbidden response but instead result in a successful alteration of the operation (and thus a 200 OK, I suspect).

Actual behavior

A 403 Forbidden response is returned even though all data provided to the Override Service Operation endpoint seems to be correct to the best of my knowledge.

How to Reproduce?

  1. Fire up a Microcks Testcontainers Java instance and import the attached OpenAPI spec.
  2. Try to install a header constraint by calling
    curl --location --request PUT 'http://localhost:32864/api/services/encoding_test_api:1/operation?operationName=`GET%20%2Fcommon%2Fgenders' \
    --header 'Content-Type: application/json' \
    --data '{
    "parameterConstraints": [
    {
      "name": "mobileTokenHeader",
      "required": "true",
      "recopy": "false",
      "mustMatchRegexp": "someToken",
      "in": "header"
    }    
    ]
    }'

(assuming that the container is reachable at http://localhost:32864). From my perspective, this call should result in extending the GET /common/genders operation with a header constraint of name mobileTokenHeader and expected fake value someToken.

encoding_test_openapi.json

Microcks version or git rev

Microcks Testcontainers Java 0.2.8 with nightly uber image

Install method (docker-compose, helm chart, operator, docker-desktop extension,...)

mvn test of a Java application that spins up the Microcks Testcontainer

Additional information

I tried to narrow down the cause of this behavior but couldn't see an issue on my side. I hops this information helps to clarify the issue (or otherwise tell me what I'm doing wrong ;-)):

lbroudoux commented 2 weeks ago

Thank you for opening this issue. You provide a lot of helpful details that may certainly accelerate the investigation. I'll probably be able to have a look at it tomorrow.

lbroudoux commented 2 weeks ago

Hi there!

So actually, this is an issue on Microcks side and not on the side of the testcontainers module.

serviceId as used in the API path has —most of the time— two different meanings. It can be the raw unique identifier used in the database to identify the service, OR it can be the service_name:service_version identifier.

In the case of this API (the operation properties update), the translation from service_name:service_version to raw identifier has not been put in place. So basically, Microcks fails to retrieve a service with this ID and then apply the update to the operation.

So basically, we would have to generalize this translation everywhere - not just on the /api/tests or /api/services/{serviceId} endpoints - but also on all the derivatives.

In the very short term, a workaround would be to first issue a call to the /api/services/{serviceId}?messages=false endpoint that could return the representation of the service and then access its 'id'. Then, reuse this id in the second call to override operation constraints.

I will create an issue on the Microcks side to track this one. Also, I think it could be nice to add these constraints specifications on the x-microcks OpenAPI extensions as well. What do you think?

We held on to constraints as they're currently managed independently of the OpenAPI parameter definitions, but we think we should have some kind of matching in the future. However, it doesn't prevent for adding them in extensions on short-mid term...

lbroudoux commented 2 weeks ago

Now tracked here: https://github.com/microcks/microcks/issues/1225