Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG][SPRING-JAVA] Wrong generation result #18710

Open
4 of 6 tasks
Shotim opened this issue May 20, 2024 · 2 comments
Open
4 of 6 tasks

[BUG][SPRING-JAVA] Wrong generation result #18710

Shotim opened this issue May 20, 2024 · 2 comments

Comments

@Shotim
Copy link

Shotim commented May 20, 2024

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

I identified several common tags for the API in the specification file

openapi-generator version

7.5.0

OpenAPI declaration file content or url
---
openapi: 3.0.0
info:
  title: Catalog API
  version: 1.0.0
tags:
  - name: Material
    description: List of All materials
  - name: Material Type
    description: List of All material types
  - name: Material Group
    description: List of All material groups
  - name: Status
    description: List of All statuses
  - name: Measurement Unit
    description: List of All measurement units
  - name: Measuring Point
    description: List of All measuring points
  - name: Document
    description: List of All documents
  - name: Document Type
    description: List of All document types

paths:
  /catalog/v1/api/material-types/{id}:
    get:
      tags:
        - Material Type
      description: Get Material Type by id
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MaterialTypeEntity'
  /catalog/v1/api/material-types:
    get:
      tags:
        - Material Type
      description: Get Material Types
      parameters:
        - name: pageNumber
          in: query
          description: page number of the list
          required: false
          schema:
            type: integer
        - name: pageSize
          in: query
          description: amount of elements on a page
          required: false
          schema:
            type: integer
        - name: sort
          in: query
          description: sort parameter
          required: false
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Page'
                  - type: object
                    properties:
                      content:
                        type: array
                        items:
                          $ref: '#/components/schemas/MaterialTypeEntity'
  /catalog/v1/api/material-groups/{id}:
    get:
      tags:
        - Material Group
      description: Get Material Group by id
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MaterialGroupEntity'
  /catalog/v1/api/material-groups:
    get:
      tags:
        - Material Group
      description: Get Material Groups
      parameters:
        - name: pageNumber
          in: query
          description: page number of the list
          required: false
          schema:
            type: integer
        - name: pageSize
          in: query
          description: amount of elements on a page
          required: false
          schema:
            type: integer
        - name: sort
          in: query
          description: sort parameter
          required: false
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Page'
                  - type: object
                    properties:
                      content:
                        type: array
                        items:
                          $ref: '#/components/schemas/MaterialGroupEntity'
  /catalog/v1/api/materials/{id}:
    get:
      tags:
        - Material
      description: Get Material by id
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MaterialEntity'
  /catalog/v1/api/materials:
    get:
      x-spring-paginated: true
      tags:
        - Material
      description: Get list of Materials
      parameters:
        - name: id
          in: query
          description: id of the required material
          required: false
          schema:
            type: string
        - name: statusId
          in: query
          description: exception status of the required material
          required: false
          schema:
            type: string
        - name: pageNumber
          in: query
          description: page number of the list
          required: false
          schema:
            type: integer
        - name: pageSize
          in: query
          description: amount of elements on a page
          required: false
          schema:
            type: integer
        - name: sort
          in: query
          description: sort parameter
          required: false
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Page'
                  - type: object
                    properties:
                      content:
                        type: array
                        items:
                          $ref: '#/components/schemas/MaterialEntity'
    post:
      tags:
        - Material
      description: Create temporal material
      requestBody:
        description: A JSON object of a temporal material
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TemporalMaterialRequest'
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemporalMaterialResponse'
  /catalog/v1/api/statuses/{id}:
    get:
      tags:
        - Status
      description: Get Status by id
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StatusEntity'
  /catalog/v1/api/statuses:
    get:
      x-spring-paginated: true
      tags:
        - Status
      description: Get list of All statuses
      parameters:
        - name: pageNumber
          in: query
          description: page number of the list
          required: false
          schema:
            type: integer
        - name: pageSize
          in: query
          description: amount of elements on a page
          required: false
          schema:
            type: integer
        - name: category
          in: query
          description: category of the status
          required: true
          schema:
            type: string
        - name: sort
          in: query
          description: sort parameter
          required: false
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Page'
                  - type: object
                    properties:
                      content:
                        type: array
                        items:
                          $ref: '#/components/schemas/StatusEntity'
  /catalog/v1/api/measurement-units/{id}:
    get:
      tags:
        - Measurement Unit
      description: Get Measurement Unit by id
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MeasurementUnitEntity'
  /catalog/v1/api/measurement-units:
    get:
      x-spring-paginated: true
      tags:
        - Measurement Unit
      description: Get list of All Measurement Units
      parameters:
        - name: pageNumber
          in: query
          description: page number of the list
          required: false
          schema:
            type: integer
        - name: pageSize
          in: query
          description: amount of elements on a page
          required: false
          schema:
            type: integer
        - name: sort
          in: query
          description: sort parameter
          required: false
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Page'
                  - type: object
                    properties:
                      content:
                        type: array
                        items:
                          $ref: '#/components/schemas/MeasurementUnitEntity'
  /catalog/v1/api/measuting-points/{id}:
    get:
      tags:
        - Measuring Point
      description: Get Measuring Point by id
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MeasuringPointEntity'
  /catalog/v1/api/measuting-points:
    get:
      x-spring-paginated: true
      tags:
        - Measuring Point
      description: Get list of All Measuring Points
      parameters:
        - name: pageNumber
          in: query
          description: page number of the list
          required: false
          schema:
            type: integer
        - name: pageSize
          in: query
          description: amount of elements on a page
          required: false
          schema:
            type: integer
        - name: sort
          in: query
          description: sort parameter
          required: false
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Page'
                  - type: object
                    properties:
                      content:
                        type: array
                        items:
                          $ref: '#/components/schemas/MeasuringPointEntity'
  /catalog/v1/api/document-types/{id}:
    get:
      tags:
        - Document Type
      description: Get Document Type by id
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentTypeEntity'
  /catalog/v1/api/document-types:
    get:
      x-spring-paginated: true
      tags:
        - Document Type
      description: Get list of All Document Types
      parameters:
        - name: pageNumber
          in: query
          description: page number of the list
          required: false
          schema:
            type: integer
        - name: pageSize
          in: query
          description: amount of elements on a page
          required: false
          schema:
            type: integer
        - name: sort
          in: query
          description: sort parameter
          required: false
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Page'
                  - type: object
                    properties:
                      content:
                        type: array
                        items:
                          $ref: '#/components/schemas/DocumentTypeEntity'
  /catalog/v1/api/documents/{id}:
    get:
      tags:
        - Document
      description: Get Document by id
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentEntity'
  /catalog/v1/api/documents:
    get:
      tags:
        - Document
      description: Get list of All Documents
      parameters:
        - name: search
          in: query
          required: false
          schema:
            type: string
        - name: techPlace
          in: query
          required: false
          schema:
            type: string
        - name: documentKind
          in: query
          required: false
          schema:
            type: string
        - name: documentTypeId
          in: query
          required: false
          schema:
            type: string
        - name: pageNumber
          in: query
          description: page number of the list
          required: false
          schema:
            type: integer
        - name: pageSize
          in: query
          description: amount of elements on a page
          required: false
          schema:
            type: integer
        - name: sort
          in: query
          description: sort parameter
          required: false
          schema:
            type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Page'
                  - type: object
                    properties:
                      content:
                        type: array
                        items:
                          $ref: '#/components/schemas/DocumentEntity'
    post:
      tags:
        - Document
      description: Create document
      requestBody:
        description: An object of a document
        content:
          multipart/form-data:
            schema:
              type: object
              required: [ file,documentKind,documentTypeId, tm/eoCode ]
              properties:
                file:
                  type: array
                  items:
                    type: string
                    format: binary
                documentKind:
                  type: string
                documentTypeId:
                  type: string
                tm/eoCode:
                  type: string
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentEntity'



components:
  schemas:
    Page:
      type: object
      properties:
        content:
          type: array
          items:
            type: object
        pageable:
          $ref: '#/components/schemas/Pageable'
        last:
          type: boolean
        totalElements:
          type: integer
        totalPages:
          type: integer
        first:
          type: boolean
        numberOfElements:
          type: integer
        empty:
          type: boolean
    Pageable:
      type: object
      properties:
        pageSize:
          type: integer
        pageNumber:
          type: integer
        sort:
          $ref: '#/components/schemas/Sort'
    Sort:
      type: object
      properties:
        sorted:
          type: boolean
        unsorted:
          type: boolean
    MaterialTypeEntity:
      required:
        - id
        - name
      properties:
        id:
          type: string
        name:
          type: string
      type: object
    MaterialGroupEntity:
      required:
        - id
        - name
      properties:
        id:
          type: string
        name:
          type: string
      type: object
    MaterialEntity:
      required:
        - id
        - name
        - price
        - measurementUnit
        - amount
        - materialTypeId
        - materialType
        - materialGroupId
        - materialGroup
      properties:
        id:
          type: string
        name:
          type: string
        price:
          type: number
        measurementUnit:
          $ref: '#/components/schemas/MeasurementUnitEntity'
        amount:
          type: integer
        materialTypeId:
          type: string
        materialType:
          $ref: '#/components/schemas/MaterialTypeEntity'
        materialGroupId:
          type: string
        materialGroup:
          $ref: '#/components/schemas/MaterialGroupEntity'
      type: object
    TemporalMaterialRequest:
      required:
        - name
        - price
        - measurementUnitId
        - amount
      properties:
        name:
          type: string
        price:
          type: number
        measurementUnitId:
          type: string
        amount:
          type: integer
      type: object
    TemporalMaterialResponse:
      required:
        - id
        - name
        - price
        - measurementUnit
        - amount
      properties:
        id:
          type: string
        name:
          type: string
        price:
          type: number
        measurementUnit:
          $ref: '#/components/schemas/MeasurementUnitEntity'
        amount:
          type: integer
      type: object
    StatusEntity:
      required:
        - id
        - name
      properties:
        id:
          type: string
        name:
          type: string
      type: object
    MeasurementUnitEntity:
      required:
        - id
        - name
      properties:
        id:
          type: string
        name:
          type: string
      type: object
    MeasuringPointEntity:
      required:
        - id
        - measuringPointKind
        - name
        - position
        - description
        - codeGroup
        - nodeId
        - type
      properties:
        id:
          type: string
        measuringPointKind:
          type: string
        name:
          type: string
        position:
          type: string
        description:
          type: string
        codeGroup:
          type: string
        nodeId:
          type: string
        type:
          type: string
      type: object
    DocumentTypeEntity:
      required:
        - id
        - name
      properties:
        id:
          type: string
        name:
          type: string
      type: object
    DocumentEntity:
      required:
        - id
        - name
        - status
        - date
        - documentKind
        - documentType
        - tm/eoCode
        - link
      properties:
        id:
          type: string
        name:
          type: string
        status:
          $ref: '#/components/schemas/StatusEntity'
        date:
          type: string
        documentKind:
          type: string
        documentType:
          $ref: '#/components/schemas/DocumentTypeEntity'
        tm/eoCode:
          type: string
        link:
          type: string
      type: object
Generation Details

I use configuration in the mvn pom.xml

<plugin>
                <groupId>org.openapitools</groupId>
                <artifactId>openapi-generator-maven-plugin</artifactId>
                <version>7.5.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <skipValidateSpec>false</skipValidateSpec>
                            <inputSpec>./src/main/resources/catalogAPI.yaml</inputSpec>
                            <generatorName>spring</generatorName>
                            <importMappings>
                                <importMapping>Pageable=org.springframework.data.domain.Pageable</importMapping>
                                <importMapping>Page=org.springframework.data.domain.PageImpl</importMapping>
                                <importMapping>Sort=org.springframework.data.domain.Sort</importMapping>
                            </importMappings>
                            <configOptions>
                                <useSpringBoot3>true</useSpringBoot3>
                                <openApiNullable>false</openApiNullable>
                                <interfaceOnly>true</interfaceOnly>
                            </configOptions>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

And I see result of

@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.5.0")
@Validated
@Tag(name = "Document Type", description = "List of All document types")
public interface CatalogApi {

And it makes for every request additional tag of Document Type when only several requests belong to it

Steps to reproduce

execution of mvn clean package

Related issues/PRs

Didn't found any

Suggest a fix

I didn't find workaround for that

@jpfinne
Copy link
Contributor

jpfinne commented May 21, 2024

All your endpoints starts with /catalog.
That produces the CatalogApi.

What you probably want is to use some configOptions described here : https://openapi-generator.tech/docs/generators/spring/

for example <useTags>true</useTags> will produce several interfaces: DocumentApi, MaterialTypeApi, MaterialGroupApi...

The other solution is to remove /catalog/v1/api from the endpoints and use only the relevant end (for example /material-types/{id})
-> it will produce a MaterialTypesApi interface

then you have 2 options:

add the following to your contract.

servers:
  - url: /catalog/v1/api

and correctly configure the configOptions requestMappingMode.

either add @RequestMapping("/catalog/v1/api") to your controllers

@Shotim
Copy link
Author

Shotim commented May 22, 2024

@jpfinne I mean, that it adds @tag annotation of Document type on a controller class and either additional tags on endpoints. So it makes additional tag for every endpoint so that I see that all endpoints belongs to Document Type tag which is wrong behaviour. Thank you for your impact!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants