OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
20.73k stars 6.32k forks source link

[java] Compilation failure when 'discriminator' is introduced #806

Open yuanpli opened 5 years ago

yuanpli commented 5 years ago
Description

I got the following error when generate code by using openapi-generator-maven-plugin.

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project swagger-vnfm: Compilation failure
[ERROR] /swagger-vnfm/target/generated-sources/src/main/java/com/openapi/test/VimConnectionInfo.java:[43,49] incompatible types: java.lang.String cannot be converted to com.openapi.test.VimType
openapi-generator version
3.2.0
OpenAPI declaration file content or url
swagger: '2.0'
info:
  description: This spec is mainly for testing
  version: 1.0.0
  title: Swagger Petstore
  termsOfService: 'http://swagger.io/terms/'
  contact:
    email: apiteam@swagger.io
  license:
    name: Apache-2.0
    url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
host: 'petstore.swagger.io:80'
basePath: /v2
paths:
  /test:
    get:
      description: Gets all operation occurrence resources.
      responses:
        '200':
          description: Successful response
          schema:
            type: string
        default:
          description: Error payload
          schema:
            type: string
      tags:
        - test
schemes:
  - http
definitions:
  VimType:
    description: Type of the VIM info structure.
    type: string
    enum:
      - OPENSTACK_V2
      - OPENSTACK_V3
      - VMWARE_VCLOUD
      - OTHER_VIM_INFO
  VimConnectionInfo:
    type: object
    required:
      - id
      - vimType
    discriminator: vimType
    properties:
      id:
        description: Identifier of the VIM
        type: string
      vimType:
        $ref: '#/definitions/VimType'
externalDocs:
  description: Find out more about Swagger
  url: 'http://swagger.io'
Command line used for generation

mvn clean compile

Steps to reproduce

The maven pom.xml is

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.vnfm.model</groupId>
    <artifactId>swagger-vnfm</artifactId>
    <packaging>jar</packaging>
    <version>DYNAMIC-SNAPSHOT</version>
    <name>swagger-vnfm</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>${swagger-core-version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>${gson-version}</version>
        </dependency>
    </dependencies>
    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <swagger-core-version>1.5.21</swagger-core-version>
        <gson-version>2.8.1</gson-version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.openapitools</groupId>
                <artifactId>openapi-generator-maven-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <execution>
                        <id>lcm-generate</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <inputSpec>${project.basedir}/src/main/resources/swagger.yaml</inputSpec>
                            <language>java</language>
                            <generateApis>false</generateApis>
                            <generateModelTests>false</generateModelTests>
                            <generateModelDocumentation>false</generateModelDocumentation>
                            <generateSupportingFiles>false</generateSupportingFiles>
                            <skipOverwrite>true</skipOverwrite>
                            <configOptions>
                                <dateLibrary>java8</dateLibrary>
                            </configOptions>
                            <output>${project.build.directory}/generated-sources</output>
                            <modelPackage>com.openapi.test</modelPackage>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
Related issues/PRs

No

Suggest a fix/enhancement
jmini commented 5 years ago

Thank you for this feedback. It is very valuable.

I think the specific issue is that your discriminator is an enum. This might be not supported yet.

Other question from my side: Is your spec complete? What is the idea behind using a discriminator here? There is no mapping and no ComposedSchema (oneOf, allOf).

yuanpli commented 5 years ago

Hi,

This swagger is provided by collaborator, and what I used here is simplified for the privacy policy. The whole definition for object VimConnectionInfo is posted as below. And there is a explanation for why used discriminator "Type of the VIM info structure. This field will be used as a discriminator for different types of VIMs.OTHER_VIM_INFOis provided for forward compatibility with later microversions of the API."

    "VimConnectionInfo": {
      "type": "object", 
      "required": [
        "id", 
        "vimType"
      ], 
      "discriminator": "vimType", 
      "properties": {
        "id": {
          "description": "Identifier of the VIM", 
          "$ref": "#/definitions/Identifier"
        }, 
        "vimType": {
          "description": "Type of the VIM info structure. This field will be used as a discriminator for different types of VIMs. `OTHER_VIM_INFO` is provided for forward compatibility with later microversions of the API.", 
          "type": "string", 
          "enum": [
            "OPENSTACK_V2", 
            "OPENSTACK_V3", 
            "VMWARE_VCLOUD", 
            "OTHER_VIM_INFO"
          ]
        }
      }, 
      "description": "This is a base type that has derivatives. In all places where it is referenced the following types should be expected: ['OPENSTACK_V2', 'OPENSTACK_V3', 'VMWARE_VCLOUD', 'OTHER_VIM_INFO']. The actual type is determined by the field 'vimType' which contains the type name.", 
      "example": {
        "id": "global_identifier_9cd6192c-899c-11e8", 
        "vimType": "OPENSTACK_V2", 
        "interfaceInfo": {
          "endpoint": "https://example.com/url"
        }, 
        "accessInfo": {
          "username": "string", 
          "password": "password", 
          "region": "string", 
          "tenant": "string"
        }
      }
    }
yuanpli commented 5 years ago

Any update?

jmini commented 5 years ago

Feel free to propose a pull request

keenanpepper commented 4 years ago

This issue appears to be fixed in 4.1.3.

antweb commented 4 years ago

Using an enum descriminator is still broken on 4.2.3 and the current master (4.3.0-SNAPSHOT).

I built a simple example based on the OpenAPI docs:

components:
  schemas:
    Pet:
      oneOf:
        - $ref: "#/components/schemas/Cat"
        - $ref: "#/components/schemas/Dog"
        - $ref: "#/components/schemas/Lizard"
      discriminator:
        propertyName: petType
        mapping:
          Cat: "#/components/schemas/Cat"
          Dog: "#/components/schemas/Dog"
          Lizard: "#/components/schemas/Lizard"

    Cat:
      type: object
      properties:
        petType:
          $ref: "#/components/schemas/PetType"
        name:
          type: string

    Dog:
      type: object
      properties:
        petType:
          $ref: "#/components/schemas/PetType"
        bark:
          type: string

    Lizard:
      type: object
      properties:
        petType:
          $ref: "#/components/schemas/PetType"
        lovesRocks:
          type: boolean

    PetType:
      type: string
      enum:
        - Cat
        - Dog
        - Lizard

Generated with

java -jar openapi-generator-cli.jar generate \
  -i api.yaml \
  --api-package 'com.test.api' \
  --model-package 'com.test.model' \
  -g java \
  --library 'retrofit2' \
  -o generated/

The issue seems to be this line in the constructor of the base type (Pet):

this.petType = this.getClass().getSimpleName();

which doesn't compile unless petType is a String. The fix should be rather simple. Whenever the discriminator is an enum, the constructor should be something like this:

this.petType = PetType.fromValue(this.getClass().getSimpleName());
mukhiparshant commented 3 years ago

Any update on this?

aeneasr commented 2 years ago

It appears this is still an issue if we have a discriminator but only one available option:

      "submitSelfServiceRecoveryFlowBody": {
        "discriminator": {
          "mapping": {
            "link": "#/components/schemas/submitSelfServiceRecoveryFlowWithLinkMethodBody"
          },
          "propertyName": "method"
        },
        "oneOf": [
          {
            "$ref": "#/components/schemas/submitSelfServiceRecoveryFlowWithLinkMethodBody"
          }
        ]
      },

Will cause:

[ERROR] /sdk/clients/client/java/src/main/java/sh/ory/model/SubmitSelfServiceRecoveryFlowBody.java:[91,47] error: incompatible types: String cannot be converted to MethodEnum

This works:

      "submitSelfServiceRecoveryFlowBody": {
        "discriminator": {
          "mapping": {
            "link": "#/components/schemas/submitSelfServiceRecoveryFlowWithLinkMethodBody",
            "foo": "#/components/schemas/something-else"
          },
          "propertyName": "method"
        },
        "oneOf": [
          {
            "$ref": "#/components/schemas/submitSelfServiceRecoveryFlowWithLinkMethodBody"
          },
          {
            "$ref": "#/components/schemas/something-else"
          }
        ]
      },
jasonrberk commented 2 years ago

exact same issue with 5.2.1 today. I can't change the spec file, as it's provided by a vendor. Not sure what my options are....

EDIT:

I switched to https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen-maven-plugin and used <version>3.0.29</version> and my models are generated successfully

<plugin>
                <groupId>io.swagger.codegen.v3</groupId>
                <artifactId>swagger-codegen-maven-plugin</artifactId>
                <version>3.0.29</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <inputSpec>${project.basedir}/src/main/resources/petstore.json</inputSpec>
                            <language>java</language>
                            <modelPackage>com.my-comp.some-vendor-we-use.models</modelPackage>
                            <withXml>true</withXml>
                            <generateApis>false</generateApis>
                            <generateModels>true</generateModels>
                            <generateModelTests>false</generateModelTests>
                            <generateModelDocumentation>true</generateModelDocumentation>
                            <generateSupportingFiles>false</generateSupportingFiles>
                            <ignoreFileOverride>${project.basedir}/.swagger-codegen-ignore</ignoreFileOverride>
                            <configOptions>
                                <sourceFolder>src/java/main</sourceFolder>
                                <bigDecimalAsString>true</bigDecimalAsString>
                                <dateLibrary>java8</dateLibrary>
<!--
library
        library template (sub-template) to use (Default: okhttp-gson)
            jersey1 - HTTP client: Jersey client 1.19.4. JSON processing: Jackson 2.10.1. Enable gzip request encoding using '-DuseGzipFeature=true'.
            feign - HTTP client: OpenFeign 9.4.0. JSON processing: Jackson 2.10.1
            jersey2 - HTTP client: Jersey client 2.26. JSON processing: Jackson 2.10.1
            okhttp-gson - HTTP client: OkHttp 2.7.5. JSON processing: Gson 2.8.1. Enable Parcelable models on Android using '-DparcelableModel=true'. Enable gzip request encoding using '-DuseGzipFeature=true'.
            retrofit - HTTP client: OkHttp 2.7.5. JSON processing: Gson 2.3.1 (Retrofit 1.9.0). IMPORTANT NOTE: retrofit1.x is no longer actively maintained so please upgrade to 'retrofit2' instead.
            retrofit2 - HTTP client: OkHttp 3.8.0. JSON processing: Gson 2.6.1 (Retrofit 2.3.0). Enable the RxJava adapter using '-DuseRxJava[2]=true'. (RxJava 1.x or 2.x)
            resttemplate - HTTP client: Spring RestTemplate 4.3.9-RELEASE. JSON processing: Jackson 2.9.9
            resteasy - HTTP client: Resteasy client 3.1.3.Final. JSON processing: Jackson 2.9.9
-->
                                <library>resteasy</library>
                                <java8>true</java8>
                            </configOptions>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

to see available configOptions use java -jar ./swagger-codegen-cli.jar config-help -l java

johnlinp commented 2 years ago

I don't think @antweb's proposed fix is a general fix. It will work on @antweb's example because the enum values (i.e. Cat, Dog, Lizard) are exactly the same with the class names. It won't work if the enum values and class names don't match, e.g. the enum values change into something like CAT_TYPE, DOG_TYPE, LIZARD_TYPE.

dnievas-tr commented 2 years ago

I'm also experiencing this issue.

RevealOscar commented 1 year ago

Same here as well

CSALS commented 9 months ago

Still facing this issue in 2023 :(

bedaka commented 7 months ago

Same here

javabean68 commented 7 months ago

Same here

jesudornenkrone commented 2 months ago

I ran into the same problem yesterday. Any ideas or plans?

kunalpmj commented 1 month ago

I am also experiencing same issue

Alamonall commented 1 month ago

Same...