OpenAPITools / OpenAPITools/openapi-generator

[BUG][JAVA] Header names being renamed when using java-micronaut-client generator

Open
#15,015 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Bug Report Checklist
  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

We have an openapi spec that we've passed through the java-micronaut-client generator.
It generates the following header in the interface method:
@Header(name="WCToken") @NotNull String wcToken

When we use this interface, we expect the http header to have the name "WCToken" as per the annotation.
However, what happens is that the header name is modified by micronaut and becomes a hyphenised version of the parameter name. It becomes "wc-token".

openapi-generator version

6.4.0

OpenAPI declaration file content or url
openapi: 3.0.1
info:
  title: Test app
  version: 1.0.0
paths:
  /profile/password:
    post:
      tags:
      - Reset Password
      description: To reset the password of the user
      parameters:
      - name: WCToken
        in: header
        required: true
        schema:
          type: string
      - name: WCTrustedToken
        in: header
        required: true
        schema:
          type: string
      requestBody:
        description: Current and new Password of the user
        content:
          application/json:
            schema:
              required:
              - logonPassword
              - logonPasswordOld
              - logonPasswordVerify
              type: object
              properties:
                logonPasswordOld:
                  type: string
                logonPassword:
                  type: string
                logonPasswordVerify:
                  type: string
              example:
                logonPasswordOld: current@123
                logonPassword: new@123
                logonPasswordVerify: new@123
      responses:
        200:
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success_ResetPassword'
        400:
          description: Bad Request. Incorrect Password
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequest_ResetPasswordError'

components:
  schemas:
    Success_ResetPassword:
      type: object
      properties:
        success:
          type: string
      example:
        success: "true"
    BadRequest_ResetPasswordError:
      type: object
      properties:
        customer:
          type: object
          properties:
            errors:
              type: array
              items:
                $ref: '#/components/schemas/BadRequest_ResetPassword_ErrorMessage'
    BadRequest_ResetPassword_ErrorMessage:
      type: object
      properties:
        message:
          type: string
        key:
          type: string
      example:
        message: Current password is wrong
        key: Current password is wrong
Generation Details
tasks.register<GenerateTask>("buildCustomerWcsClient") {
    validateSpec.set(true)

    inputSpec.set(wcsCustomerSpecFile)
    outputDir.set(generatedOutput)
    apiPackage.set("com.identity.client.wcs.operation")
    modelPackage.set("com.identity.client.wcs.model")
    configOptions.putAll(
        mapOf(
            "reactive" to "true",
            "wrapInHttpResponse" to "true",
            "applicationName" to "wcs",
            "configureAuth" to "true",
        )
    )
    generateApiTests.set(false)
    generateModelTests.set(false)

    generatorName.set("java-micronaut-client")
}
Steps to reproduce
  • Generate the client interfaces from the spec above
  • You'll notice the parameter for the http headers are annotated with @Header(name="WCToken") and @Header(name="WCTrustedToken")
  • When you call this interface, you'll see that the headers are not sent with the names "WCToken" and "WCTrustedToken", as specified, they will be called "wc-token" and "wc-trusted-token"
Related issues/PRs

I've opened an issue with micronaut, but they said this is expected behaviour in the way the code was generated. The "value" attribute of the annotation should have been used, instead of the "name" attribute.

Here's the issue URL: https://github.com/micronaut-projects/micronaut-core/issues/8908

I've done some debugging of the micronaut classes, so I'll provide some information that may be useful:
When we call the generated interface, it is intercepted by HttpClientIntroductionAdvice.
Because a custom binder is not found, this Header annotation is processed by the DefaultHttpClientBinderRegistry.
The "byAnnotation" field with the key of "Header.class" is used for getting the header name. It looks for the annotation's value (which is null, as the generator has set the name, not the value). Because it's null, the binderRegistry uses the parameter name as the basis for the http header.

Suggest a fix

Generate the code using the "value" attribute of the @Header annotation, not the "name" attribute.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the java-micronaut-client generator entry point and the API template that emits the generated interface annotations. Reproduce the issue with the supplied OpenAPI YAML, then inspect the generated WCToken and WCTrustedToken parameters. Done means the annotation uses the value attribute and the generated client sends the exact header names from the specification.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.