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][openapi-generator-maven-plugin] importmapping not respected since 5.4.0 #11506

Closed
4 of 6 tasks
meierval opened this issue Feb 3, 2022 · 27 comments · Fixed by #12600
Closed
4 of 6 tasks

[BUG][openapi-generator-maven-plugin] importmapping not respected since 5.4.0 #11506

meierval opened this issue Feb 3, 2022 · 27 comments · Fixed by #12600

Comments

@meierval
Copy link

meierval commented Feb 3, 2022

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue? Yes, inside attached ZIP
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists? -> No, but tested with 5.4.0
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output? Expected: StreamingResponseBody, Actual: Stream
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

The "importMappings" seem to have no effect with version 5.4.0.
With version 5.3.1 the below configuration resulted in a "StreamingResponseBody" in the generated class.
With version 5.4.0 a "Stream" class is imported but that one does not exist.

openapi-generator version

Issue occurs with openapi-generator-maven-plugin 5.4.0 and did not occur with the previous version 5.3.1.

OpenAPI declaration file content or url

If you post the code inline, please wrap it with

openapi: 3.0.3
info:
  title: Demo app
  version: 1.0.0
servers:
  - url: /api/v1
paths:
  /demo:
    get:
      summary: Demo
      operationId: demo
      responses:
        '200':
          description: Demo response
          content:
            text/csv:
              schema:
                type: string
                format: binary
Generation Details

Plugin configuration:

      <plugin>
        <groupId>org.openapitools</groupId>
        <artifactId>openapi-generator-maven-plugin</artifactId>
        <!-- With version 5.3.1 of the plugin, the generated "DemoApi.java" contains default org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody as expected -->
        <!-- With version 5.4.0 of the plugin, the generated "DemoApi.java" contains "Stream", but the org.example.bug.demo.api.Stream is not created -->
        <version>5.4.0</version>
        <executions>
          <execution>
            <id>bug-demo</id>
            <goals>
              <goal>generate</goal>
            </goals>
            <configuration>
              <inputSpec>${project.basedir}/src/main/resources/spec.yaml</inputSpec>
              <generatorName>spring</generatorName>
              <apiPackage>org.example.bug.demo.api</apiPackage>
              <modelPackage>org.example.bug.demo.api</modelPackage>
              <configOptions>
                <delegatePattern>true</delegatePattern>
              </configOptions>
              <importMappings>
                stream=org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody
              </importMappings>
              <typeMappings>string+binary=stream</typeMappings>
            </configuration>
          </execution>
        </executions>
      </plugin>
Steps to reproduce

Run mvn clean install on the attached demo project.

Related issues/PRs

No similar issues.

Suggest a fix

Not sure what causes the problems, but I assume it has to do with this change:
#11217

bug Demo application

bug-demo.zip

@exaV
Copy link
Contributor

exaV commented Feb 4, 2022

I just encountered the a similar issue after upgrading to 5.4.0

Classes specified in importMappings are ignored and generated anyway.

Here's an example:

components:
  schemas:
    I18nString:
      type: object
      required:
        - translation
      properties:
        localisedText:
          type: string
        translation:
          type: object
          additionalProperties:
            type: string
<plugin>
        <groupId>org.openapitools</groupId>
        <artifactId>openapi-generator-maven-plugin</artifactId>
        <!-- With version 5.3.1 of the plugin, the generated "DemoApi.java" contains default org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody as expected -->
        <!-- With version 5.4.0 of the plugin, the generated "DemoApi.java" contains "Stream", but the org.example.bug.demo.api.Stream is not created -->
        <version>5.4.0</version>
        <executions>
          <execution>
            <id>bug-demo</id>
            <goals>
              <goal>generate</goal>
            </goals>
            <configuration>
              <inputSpec>${project.basedir}/src/main/resources/spec.yaml</inputSpec>
              <generatorName>spring</generatorName>
              <apiPackage>org.example.bug.demo.api</apiPackage>
              <modelPackage>org.example.bug.demo.api</modelPackage>
              <configOptions>
                                <exceptionHandler>false</exceptionHandler>>
                                <serializationLibrary>jackson</serializationLibrary>
                                <useTags>true</useTags>
                                <enumPropertyNaming>UPPERCASE</enumPropertyNaming>
                                <library>spring-boot</library>
              </configOptions>
              <importMappings>
                    <importMapping>
                        I18nString=our.custom.library.I18nStringDTO,
                    </importMapping>
                </importMappings>
            </configuration>
          </execution>
        </executions>
      </plugin>  

@cachescrubber
Copy link
Contributor

I see the issue as well. The mapped imports are used in the generated Model, but the Model targeted by the importmapping is generated anyway.

@sigand
Copy link
Contributor

sigand commented Feb 16, 2022

Same, but for the gradle plugin

@clemjt
Copy link

clemjt commented Feb 21, 2022

Same here

@WIStudent
Copy link

WIStudent commented Feb 21, 2022

Seems to me that #11217 removed the usage of the import mappings in the generated model. Additionally, defined import mappings will no longer be skipped during the model generation.

We were relying heavily on this behavior to fix issues the spring generator has with anyOf/oneOf (by defining models that use anyOf/oneOf and setting them as import mappings).

@wing328 Is there any other way to use our own models? What's described in https://openapi-generator.tech/docs/customization/#bringing-your-own-models no longer works.

@UnleashSpirit
Copy link
Contributor

UnleashSpirit commented Feb 24, 2022

Same here, this is a "big regression" for us as we use it very often
For exemple, lots of openapi files in the same java projet using same "Error" model that we want to be "merge" in one. Avoiding import from multiple package (one package per api file)

Any clue why removing this needed feature ?
#11217 is a bit "empty"

@jorgerod
Copy link
Contributor

Hi
We have the same problem. For us, this feature is very important.
Is there any workaround or other way to do it?

In case of a fix for this bug, would it be released in a 5.4.x version?

@wing328 @bbdouglas @sreeshas @jfiala @lukoyanov @cbornet @jeff9finger @karismann @Zomzog @lwlee2608

Thank you very much

@wing328
Copy link
Member

wing328 commented Feb 26, 2022

For those impacted by this, please revert to v5.3.1 for the time being.

We need to come up with something else (e.g. schemaMapping) as importMapping was not designed for skipping model generation. (the logic for reusing importMapping to skip model generation was added in 4.x if I remember correctly)

I'll try to come up with a fix for the v6.0.0 release.

For those who want to repeat the issue fixed by #11217, define a model named "List" and you will see the model not being generated (which is not the correct behaviour) when using the Java client generator.

Have a nice weekend everyone.

@gong4soft
Copy link

@wing328 thanks for working on this, I understand it like the 6.0.0 version will introduce schemaMapping for skipping model generation, right?

@IncPlusPlus
Copy link
Contributor

IncPlusPlus commented May 21, 2022

I previously used importMapping to be able to use Java's ZonedDateTime type for the OpenAPI date-time string format. By default, the field would be a java.time.OffsetDateTime. The configuration used to look like this (I'm using Gradle):

configOptions = [
  'dateLibrary': 'custom',
]
typeMappings = [
    'DateTime': 'ZonedDateTime',
]
importMappings = [
    'ZonedDateTime': 'java.time.ZonedDateTime'
]

With that configuration, the fields would be declared in the generated file with the fully qualified java.time.ZonedDateTime type. Since 5.4.0, the generated field is now of type "ZonedDateTimeDto" and there's an import statement at the top of the file now as if it's expecting there to be a DTO with that name.

My current workaround is by removing importMappings entirely and doing the following:

configOptions = [
  'dateLibrary': 'custom',
]
typeMappings = [
  'DateTime': 'java.time.ZonedDateTime',
]

Looking at the Gradle plugin's configuration options, it seems like using only typeMappings should be fine for me as a long-term solution. I guess the only reason I previously needed importMappings was if I didn't want to specify the whole package name in the typeMappings section.

@exaV
Copy link
Contributor

exaV commented May 23, 2022

@IncPlusPlus I tried to use typeMappings instead of importMappings since from the documentation it is not immediately clear what the difference is.

It seems like the typeMappingDateTime= java.time.ZonedDateTime will perform a substitution of all occurrences of DateTime with java.time.ZonedDateTime in the api specification. In your case java.time.ZonedDateTime is not a valid identifier so it will be transformed to something like JavatimeZonedDateTime. It seems like that option is used to solve an entirely different problem.

What I am looking for is a way to skip codegen for some models and just use an import/fqn instead. Before 5.4.0 that could be done with importMappings.

@jorgerod
Copy link
Contributor

For those impacted by this, please revert to v5.3.1 for the time being.

We need to come up with something else (e.g. schemaMapping) as importMapping was not designed for skipping model generation. (the logic for reusing importMapping to skip model generation was added in 4.x if I remember correctly)

I'll try to come up with a fix for the v6.0.0 release.

For those who want to repeat the issue fixed by #11217, define a model named "List" and you will see the model not being generated (which is not the correct behaviour) when using the Java client generator.

Have a nice weekend everyone.

Hi @wing328

In version 6.0.0, has this problem been fixed?

Thank you

@Heatmanofurioso
Copy link

Hi,

Any news on this issue?

@charboubmustapha
Copy link

Even in the version 5.3.1the problem is still there

@WIStudent
Copy link

I might have a workaround if you can choose the name and location of your own model freely:

Create an .openapi-generator-ignore file in your project and add all model files you do not want openapi-generator to generate

target/generated-sources/openapi/src/main/java/com/example/myproject/openapi/model/MyOwnModel.java
target/generated-sources/openapi/src/main/java/com/example/myproject/openapi/model/MyOwnSubModel.java

Use that file in your openapi-generator-maven-plugin configuration:

<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>6.0.0</version>
    <executions>
        <execution>
            <id>openapi-generator-server</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <generatorName>spring</generatorName>
                <modelPackage>com.example.myproject.openapi.model</modelPackage>
                <ignoreFileOverride>
                    ./.openapi-generator-ignore
                </ignoreFileOverride>
            </configuration>
        </execution>
    </executions>
</plugin>

Now move your own implementation to src/main/java/com/example/myproject/openapi/model/MyOwnModel.java. It is important that your own model class uses the same name that openapi would use for the generated class.

@aegliv
Copy link

aegliv commented Jun 9, 2022

I reference an external schema in my openapi spec:

    MyRequest:
      type: object
      properties:
        ...
        my_external_properties:
          type: array
          items:
            $ref: 'http://openapi-host.example.com/#/components/schemas/ExternalDto'

To avoid duplicated Dtos I found following workaround:

  1. Make sure the external dependency is on your classpath

  2. Use typeMappings instead of importMappings in your configuration

 <plugin>
        <groupId>org.openapitools</groupId>
        <artifactId>openapi-generator-maven-plugin</artifactId>
        <version>5.4.0</version>
        <!-- TODO Remove this dependency-overrides when openapi-generator-maven-plugin (>5.4.0) has a dependency to
     openapi-generator (>5.4.0) that has a dependency to
     io.swagger.parser.v3:swagger-parser (>2.0.26)
     This is because there is an issue with parsing absolute $ref that causes those to be parsed as if they where relative.
     2.0.26: https://github.com/swagger-api/swagger-parser/blob/987fa8c632d01887bc0e901106edfc6e5f857bc6/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java#L281
     2.0.31: https://github.com/swagger-api/swagger-parser/blob/2ba563c25d658fa2203d2317f0b2a08f97c95749/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java#L281 -->
        <dependencies>
          <dependency>
            <groupId>io.swagger.core.v3</groupId>
            <artifactId>swagger-core</artifactId>
            <version>2.1.13</version>
          </dependency>
          <dependency>
            <groupId>io.swagger.parser.v3</groupId>
            <artifactId>swagger-parser</artifactId>
            <version>2.0.31</version>
          </dependency>
        </dependencies>
        <executions>
<execution>
            <id>generate-java-api-interface</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>generate</goal>
            </goals>
            <configuration>
              <!--
                 See: https://openapi-generator.tech/docs/generators/spring
              -->
              <generatorName>spring</generatorName>
              <output>.</output>
              <generateModels>true</generateModels>
              <modelPackage>${openapi.java.modelPackage}</modelPackage>
              <generateApis>true</generateApis>
              <apiPackage>${openapi.java.apiPackage}</apiPackage>
              <modelNameSuffix>Dto</modelNameSuffix>

              <!-- Use external Dtos (see dependencies)-->
              <typeMappings>
                <typeMapping>External=org.my.other.depnendecy.ExternalDto</typeMapping>
              </typeMappings>
         </configuration>
  1. Exclude all external referenced schemas via .openapi-generator-ignore
  2. Remove unused import of duplicated Dto. I used following maven plugin for this:
  <plugin>
        <groupId>net.revelc.code</groupId>
        <artifactId>impsort-maven-plugin</artifactId>
        <version>1.7.0</version>
        <configuration>
          <removeUnused>true</removeUnused>
          <directories>
            <directory>${openapi.java.sourceDir}</directory>
          </directories>
        </configuration>
        <executions>
          <execution>
            <id>remove-unsued-imports</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>sort</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

@wing328
Copy link
Member

wing328 commented Jun 18, 2022

Hi all, I've filed #12600 to add back the functionality. Please give it a try to see if it works for your use cases.

@wing328 wing328 mentioned this issue Jun 18, 2022
5 tasks
@AshwinPrabhuB
Copy link

I used to rely on to substitute OffsetDateTime with Instant.

This no longer works, but the workaround meanwhile is to use a fully qualified class name in . In my case OffsetDateTime=java.time.Instant helps generate the right types with the minor inconvenience of seeing fully qualified class names for substituted types. The original import statement "import java.time.OffsetDateTime;" appears in the generated but remains unused.

@jorgerod
Copy link
Contributor

jorgerod commented Jul 5, 2022

Hi all, I've filed #12600 to add back the functionality. Please give it a try to see if it works for your use cases.

Hi @wing328

I have tried version 6.0.1 and it still does not work in my use case.
I have tried the demo that @meierval attached and it doesn't work either.

Could you reopen the issue? I think this issue is very important.

@jorgerod
Copy link
Contributor

jorgerod commented Jul 5, 2022

Hi all, I've filed #12600 to add back the functionality. Please give it a try to see if it works for your use cases.

Hi @wing328

I have tried version 6.0.1 and it still does not work in my use case. I have tried the demo that @meierval attached and it doesn't work either.

Could you reopen the issue? I think this issue is very important.

Sorry, using schemamapping instead of importmapping works fine in version 6.0.1

Thank you very much @wing328

@foxpluto
Copy link

@jorgerod sorry could you provide a little snip of code to clarify the case?

Thanks,
S.

@enricojonas
Copy link

@jorgerod would you mind to share a code snippet as @foxpluto also requested? I cannot get the schemaMappings to work, using the latest version 6.2.1.

Thank you!

@gong4soft
Copy link

The following configuration works for us:

<configuration>
    <!-- some other configurations -->
    <schemaMappings>External=org.my.other.depnendecy.ExternalDto</schemaMappings>
 </configuration>

@jorgerod
Copy link
Contributor

The following configuration works for us:

<configuration>
    <!-- some other configurations -->
    <schemaMappings>External=org.my.other.depnendecy.ExternalDto</schemaMappings>
 </configuration>

@enricojonas sorry, I just saw your message. With the configuration that @gong4soft gives you it works

@enricojonas
Copy link

@jorgerod @gong4soft thanks for sharing. I tried it and unfortunately it doesn't do anything.

<schemaMappings>Double=java.math.BigDecimal</schemaMappings>

I have a couple of

type: number
format: double

in the API spec that I need to map to Java BigDecimal. Trying with the latest version 6.2.1.

<typeMappings>Double=java.math.BigDecimal</typeMappings>

works but then it does not do the import but instead inserts the full class name everywhere.

@tobiashochguertel
Copy link

tobiashochguertel commented Dec 3, 2022

The following configuration works for us:

File: config.spring.yaml

---
apiPackage: work.hochguertel.quiz.api
basePackage: work.hochguertel.quiz.api
invokerPackage: work.hochguertel.quiz.api
dateLibrary: java8
delegatePattern: true
generatorName: spring
library: spring-boot
modelPackage: work.hochguertel.quiz.api.model
sourceFolder: src/main/java/
interfaceOnly: true
hideGenerationTimestamp: true
serializableModel: true
useTags: true
hateoas: true
withXml: true
supportingFilesToGenerate: ApiUtil.java
importMappings:
  ResourceSupport: org.springframework.hateoas.RepresentationModel
  Link: org.springframework.hateoas.Link
  Links: org.springframework.hateoas.Links
  Pageable: org.springframework.data.domain.Pageable
  Page: org.springframework.data.domain.Page
typeMappings:
  ResourceSupport: org.springframework.hateoas.RepresentationModel
  Link: org.springframework.hateoas.Link
  Links: org.springframework.hateoas.Links
  Pageable: org.springframework.data.domain.Pageable
  Page: org.springframework.data.domain.Page
schemaMappings:
  ResourceSupport: org.springframework.hateoas.RepresentationModel
  Link: org.springframework.hateoas.Link
  Links: org.springframework.hateoas.Links
  Pageable: org.springframework.data.domain.Pageable
  Page: org.springframework.data.domain.Page

File: api-v1.0.0.yaml

openapi: 3.0.3
info:
  title: Title
  description: Title
  version: 1.0.0
servers:
  - url: 'http://localhost:8082/api/v1'
tags:
  - name: Question
    description: Everything about questions.
  - name: Result
    description: Everything about results of a exam.
  - name: Category
    description: Everything about categories.

paths:
  /api/v1.0.0/questions/{questionId}:
    get:
      tags:
        - Question
      summary: Returns a single question.
      description: Returns the question with the given question ID.
      operationId: getQuestionById
      parameters:
        - $ref: '#/components/parameters/questionId'
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Question'
            application/xml:
              schema:
                $ref: '#/components/schemas/Question'
        404:
          description: Given question ID doesn't exist
          content: { }
    put:
      tags:
        - Question
      summary: Updates a single question.
      description: Updates the question with the given questionID.
      operationId: updateQuestion
      parameters:
        - $ref: '#/components/parameters/questionId'
      requestBody:
        description: Question object
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Question'
          application/xml:
            schema:
              $ref: '#/components/schemas/Question'
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Question'
            application/xml:
              schema:
                $ref: '#/components/schemas/Question'
        404:
          description: Question with ID doesn't exist.
          content: { }
    delete:
      tags:
        - Question
      summary: Deletes a single question.
      description: Deletes the question with the given questionID.
      operationId: deleteQuestion
      parameters:
        - $ref: '#/components/parameters/questionId'
      responses:
        200:
          description: successful operation
          content: { }
        404:
          description: Question with ID doesn't exist.
          content: { }

  /api/v1.0.0/questions:
    get:
      tags:
        - Question
      summary: Returns a collection of questions.
      description: Returns all available questions.
      operationId: getQuestions
      parameters:
        - in: query
          name: pageable
          required: false
          schema:
            $ref: '#/components/schemas/Pageable'
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Question'
            application/xml:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Question'
    post:
      tags:
        - Question
      summary: Creates a new Question
      description: Creates a new question with answers and explainations
      operationId: createQuestion
      requestBody:
        description: Question object
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Question'
          application/xml:
            schema:
              $ref: '#/components/schemas/Question'
      responses:
        201:
          description: Question added successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Question'
            application/xml:
              schema:
                $ref: '#/components/schemas/Question'

  /api/v1.0.0/categories/{categoryId}:
    get:
      tags:
        - Category
      summary: Returns a given Category.
      description: Returns a given Category.
      operationId: getCategoryById
      parameters:
        - $ref: '#/components/parameters/categoryId'
      responses:
        200:
          description: Category found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Category'
            application/xml:
              schema:
                $ref: '#/components/schemas/Category'
        404:
          description: Category with ID doesn't exist.
          content: { }
    put:
      tags:
        - Category
      summary: Updates a existing Category.
      description: Updates a existing Category.
      operationId: updatesCategory
      parameters:
        - $ref: '#/components/parameters/categoryId'
      requestBody:
        description: Category Object
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CategoryUpdate'
          application/xml:
            schema:
              $ref: '#/components/schemas/CategoryUpdate'
      responses:
        200:
          description: Category successfully updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Category'
            application/xml:
              schema:
                $ref: '#/components/schemas/Category'
        404:
          description: Category with ID doesn't exist.
          content: { }
    delete:
      tags:
        - Category
      summary: Deletes a existing Category.
      description: Deletes a existing Category.
      operationId: deleteCategory
      parameters:
        - $ref: '#/components/parameters/categoryId'
      responses:
        200:
          description: Category successfully deleted.
          content: { }
        404:
          description: Category with ID doesn't exist.
          content: { }

  /api/v1.0.0/categories:
    get:
      tags:
        - Category
      summary: Returns a collection of categories.
      description: Returns all available categories.
      operationId: getCategories
      parameters:
        - in: query
          name: pageable
          required: false
          schema:
            $ref: '#/components/schemas/Pageable'
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Category'
            application/xml:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Category'
    #          content:
    #            application/json:
    #              schema:
    #                type: object
    #                properties:
    #                  questions:
    #                    type: array
    #                    items:
    #                      $ref: '#/components/schemas/Category'
    #                  page:
    #                    $ref: '#/components/schemas/Page'
    #            application/xml:
    #              schema:
    #                type: object
    #                properties:
    #                  questions:
    #                    type: array
    #                    items:
    #                      $ref: '#/components/schemas/Category'
    #                  page:
    #                    $ref: '#/components/schemas/Page'
    post:
      tags:
        - Category
      summary: Creates a new Category.
      description: Creates a new Category.
      operationId: createCategory
      requestBody:
        description: Category Object
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Category'
          application/xml:
            schema:
              $ref: '#/components/schemas/Category'
      responses:
        201:
          description: Category successfully created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Category'
            application/xml:
              schema:
                $ref: '#/components/schemas/Category'

  /api/v1.0.0/questionresult/{questionId}:
    post:
      tags:
        - Result
      summary: Creates a result report of one question
      description: Evaluates the given answers for a given question.
      operationId: evaluateGivenAnswer
      parameters:
        - $ref: '#/components/parameters/questionId'
      requestBody:
        description: Question object
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QuestionAnswer'
          application/xml:
            schema:
              $ref: '#/components/schemas/QuestionAnswer'
      responses:
        201:
          description: Question result successfully created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuestionResult'
            application/xml:
              schema:
                $ref: '#/components/schemas/QuestionResult'
        404:
          description: Question with ID doesn't exist.
          content: { }

  /api/v1.0.0/questionresult:
    post:
      tags:
        - Result
      summary: Creates a Exam Report.
      description: Evaluates the Exam.
      operationId: evaluate
      requestBody:
        description: Object which represents a Exam report
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/ExamQuestionAnswer'
          application/xml:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/ExamQuestionAnswer'
      responses:
        201:
          description: Exam result successfully created.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/QuestionResult'
            application/xml:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/QuestionResult'

components:
  responses:
    NotFound:
      description: The specified resource was not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
        application/xml:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Unauthorized.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
        application/xml:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    Error:
      type: object
      properties:
        code:
          type: string
        message:
          type: string
      required:
        - code
        - message

    Question:
      description: a Object what represents a Multiple Choice question with answers.
      type: object
      properties:
        id:
          description: Identifier
          type: string
        quest:
          description: Question itself as sentence (with Markdown code).
          type: string
        draft:
          description: Marks a question as draft or not.
          type: boolean
        answers:
          description: List of possibles Answers
          type: array
          items:
            $ref: '#/components/schemas/Answer'

    Answer:
      description: Represents a Answering option, with explaination and if it's valid answer.
      type: object
      properties:
        statement:
          description: Answer statement (with Markdown code).
          type: string
        correct:
          description: Is this a valid or a wrong answer?
          type: boolean
        explanation:
          description: Explains why this Answer is valid or wrong (with Markdown code).
          type: string

    QuestionAnswer:
      description: Represents a given Answer by a student for one Question. Index of the array represents the choice of answer per question.
      type: array
      items:
        description: Each Index represents the choiced answer of the user from the array of answers of the question.
        type: boolean

    ExamQuestionAnswer:
      description: Question and user's choices.
      type: object
      properties:
        question:
          description: Question Identifier
          type: string
        givenAnswers:
          description: Represents a given Answer by a student for one Question. Index of the array represents the choice of answer per question.
          type: array
          items:
            description: Each Index represents the choiced answer of the user from the array of answers of the question.
            type: boolean

    Category:
      description: Represents a union of questions
      type: object
      properties:
        id:
          description: Identifier
          type: string
        name:
          description: name of the category.
          type: string
        questions:
          type: array
          items:
            $ref: '#/components/schemas/Question'

    CategoryUpdate:
      description: Represents a List of Questions.
      type: object
      properties:
        name:
          description: name of the category.
          type: string
        questions:
          type: array
          items:
            type: string

    QuestionResult:
      description: Represents a answer-sheet of one question
      type: object
      properties:
        question:
          $ref: '#/components/schemas/Question'
        your_choices:
          description: list of boolean values, which represents students answer choices on the answer sheet.
          type: array
          items:
            type: boolean
        checked_results:
          description: list of boolean values, which represents which answer of the student was correct or wrong.
          type: array
          items:
            type: boolean
        explainations:
          description: list of string values, which gives for each answer (positioned) the explaination of the answer statement.
          type: array
          items:
            type: string
        validation:
          description: list of boolean values, which represents the correct and wrong answers (positioned).
          type: array
          items:
            type: boolean

    Links:
      description: HATEOAS Links
      type: object
      properties:
        first:
          $ref: "#/components/schemas/_href"
        self:
          $ref: "#/components/schemas/_href"
        next:
          $ref: "#/components/schemas/_href"
        last:
          $ref: "#/components/schemas/_href"
        profile:
          $ref: "#/components/schemas/_href"
        search:
          $ref: "#/components/schemas/_href"

    Pageable:
      description: Pagination
      type: object
      properties:
        pageNumber:
          description: the page to be returned.
          type: number
        pageSize:
          description: the number of items to be returned.
          type: number
        offset:
          description: the offset to be taken according to the underlying page and page size.
          type: number
        sort:
          description: the sorting parameters.
          type: number
    
    Page:
      description: Pagination
      type: object
      properties:
        size:
          description: Amount of items on this page.
          type: number
        totalElements:
          description: Total amount of items of the resource.
          type: number
        totalPages:
          description: Total amount of pages for this resource.
          type: number
        number:
          description: Current page number.
          type: number

    _href:
      description: Link to a resource
      type: object
      properties:
        href:
          description: URL
          type: string

  parameters:
    questionId:
      name: questionId
      in: path
      description: Question Identifier
      required: true
      schema:
        type: string
    categoryId:
      name: categoryId
      in: path
      description: Category Identifier
      required: true
      schema:
        type: string
npx @openapitools/openapi-generator-cli generate -c ../../quiz/openapi/config.spring.yaml -i ../../quiz/openapi/api-v1.0.0.yaml -o ./build/openapi/spring

Output:
grafik

No Pageable, or Page class got generated.

$ npx @openapitools/openapi-generator-cli version
6.2.1

martin-mfg added a commit to martin-mfg/openapi-generator that referenced this issue Apr 25, 2023
@Delegant
Copy link

Delegant commented Jun 17, 2023

I would like to draw attention to the fact that the names in the type mapping are case-sensitive. In other words, if you write:

<configuration>
    <!-- some other configurations -->
    <schemaMappings>External=org.my.other.depnendecy.ExternalDto</schemaMappings>
 </configuration>

the schema should be as follows:

components:
  schemas:
    ExternalDto:
      # some config

Using lowercase naming also worked, but if you write the mapping like this:

<configuration>
    <!-- some other configurations -->
    <schemaMappings>External=org.my.other.depnendecy.ExternalDto</schemaMappings>
 </configuration>

and the schema like this:

components:
  schemas:
    externalDto:
      # some config

the DTO is still being created.

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

Successfully merging a pull request may close this issue.