openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

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

Open jvictorcf opened this issue 2 years ago • 2 comments

Bug Report Checklist

  • [x] Have you provided a full/minimal spec to reproduce the issue?
  • [x] Have you validated the input using an OpenAPI validator (example)?
  • [ ] Have you tested with the latest master to confirm the issue still exists?
  • [x] Have you searched for related issues/PRs?
  • [x] 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.

jvictorcf avatar Mar 21 '23 15:03 jvictorcf

/cc @andriy-dmytruk

graemerocher avatar Mar 21 '23 16:03 graemerocher

Already fixed.

Just use official micronaut generator for java and kotlin by micronaut-opeanpi gradle or maven plugin from this repo: https://github.com/micronaut-projects/micronaut-openapi

Look to this guide: https://guides.micronaut.io/latest/micronaut-openapi-generator-server.html

Also, please describe problems and suggestions here: https://github.com/micronaut-projects/micronaut-openapi/issues

altro3 avatar Aug 27 '24 07:08 altro3