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
21.3k stars 6.44k forks source link

[6.2.1] [Spring-Boot] OpenApi generator generates a BLANK interface for "spring" (library: spring-boot) for model with "OneOf" in the schema. #14807

Open sujeet-banerjee opened 1 year ago

sujeet-banerjee commented 1 year ago
Description

Summary: Using Maven plugin, the openapi generator (6.2.1) creates a BLANK interface (shown below 'VnfLcmOpOcc'), as opposed to Pojo.


import java.net.URI;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
...
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.format.annotation.DateTimeFormat;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.openapitools.jackson.nullable.JsonNullable;
import java.time.OffsetDateTime;
import javax.validation.Valid;
import javax.validation.constraints.*; 
import io.swagger.v3.oas.annotations.media.Schema;
...

import java.util.*;
import javax.annotation.Generated;

@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2023-02-24T12:20:32.768254+05:30[Asia/Kolkata]")
public interface VnfLcmOpOcc {
}

FYI: The declaration/swagger defines properties for the Type "VnfLcmOpOcc" (swagger/declaration link given in the sections below).

Upon some debugging, it appears that the generator INCORRECTLY assigns x-is-one-of-interface=true for the property 'changedInfo':

minimum='null', maximum='null', exclusiveMinimum=false, exclusiveMaximum=false, required=true, deprecated=false, hasMoreNonReadOnly=false, isPrimitiveType=false, isModel=true, isContainer=false, isString=false, isNumeric=false, isInteger=false, isShort=false, isLong=false, isUnboundedInteger=false, isNumber=false, isFloat=false, isDouble=false, isDecimal=false, isByteArray=false, isBinary=false, isFile=false, isBoolean=false, isDate=false, isDateTime=false, isUuid=false, isUri=false, isEmail=false, isFreeFormObject=false, isArray=false, isMap=false, isEnum=false, isInnerEnum=false, isAnyType=false, isReadOnly=false, isWriteOnly=false, isNullable=false, isSelfReference=false, isCircularReference=false, isDiscriminator=false, _enum=null, allowableValues=null, items=null, additionalProperties=null, vars=[], requiredVars=[], mostInnerItems=null, vendorExtensions={}, hasValidation=false, isInherited=false, discriminatorValue='null', nameInCamelCase='VnfInstance', nameInSnakeCase='VNF_INSTANCE', enumName='null', maxItems=null, minItems=null, maxProperties=null, minProperties=null, uniqueItems=false, uniqueItemsBoolean=null, multipleOf=null, isXmlAttribute=false, xmlPrefix='null', xmlName='null', xmlNamespace='null', isXmlWrapped=false, isNull=false, getAdditionalPropertiesIsAnyType=false, getHasVars=false, getHasRequired=false, getHasDiscriminatorWithNonEmptyMapping=false, composedSchemas=null, hasMultipleTypes=false, requiredVarsMap=null, ref=#/components/schemas/Link, schemaIsFromAdditionalProperties=false, isBooleanSchemaTrue=false, isBooleanSchemaFalse=false, format=null, dependentRequired=null, contains=null}}, ref=null, schemaIsFromAdditionalProperties=false, isBooleanSchemaTrue=false, isBooleanSchemaFalse=false, format=null, dependentRequired=null, contains=null}], parentVars=[], allowableValues=null, mandatory=[id, isAutomaticInvocation, isCancelPending, operation, operationState, startTime, stateEnteredTime, vnfInstanceId], allMandatory=[changedInfo, id, isAutomaticInvocation, isCancelPending, operation, operationState, startTime, stateEnteredTime, vnfInstanceId], imports=[AffectedExtLinkPort, AffectedVipCp, AffectedVirtualLink, AffectedVirtualStorage, AffectedVnfc, ArrayList, CancelModeType, DateTimeFormat, ExtVirtualLinkInfo, JsonProperty, LcmCoordResultType, LcmOperationStateType, LcmOperationType, Link, List, Map, ModificationsTriggeredByVnfPkgChange, OffsetDateTime, ProblemDetails, VnfInfoModifications], hasVars=true, emptyVars=true, hasMoreModels=false, hasEnums=false, isEnum=false, isNullable=false, hasRequired=true, hasOptional=true, isArray=false, hasChildren=false, isMap=true, isDeprecated=false, hasOnlyReadOnly=false, externalDocumentation=null, vendorExtensions={x-one-of-name=VnfLcmOpOcc, x-is-one-of-interface=true}, additionalPropertiesType='null', maxProperties=null, minProperties=null, uniqueItems=false, uniqueItemsBoolean=null, maxItems=null, minItems=null, maxLength=null, minLength=null, exclusiveMinimum=false, exclusiveMaximum=false, minimum='null', maximum='null', pattern='null', multipleOf='null', items='null', additionalProperties='null', isModel='true', isNull='false, hasValidation='false, getAdditionalPropertiesIsAnyType=false, getHasDiscriminatorWithNonEmptyMapping=false, getIsAnyType=false, composedSchemas=CodegenComposedSchemas{oneOf=[CodegenProperty{openApiType='Object', baseName='one_of_0', complexType='null', getter='getOneOf0', setter='setOneOf0', description='null', dataType='Object', datatypeWithEnum='Object', dataFormat='null', name='oneOf0', min='null', max='null', defaultValue='null', defaultValueWithParam=' = data.one_of_0;', baseType='Object', containerType='null', title='null', unescapedDescription='null', maxLength=null, minLength=null, pattern='null', example='null', jsonSchema='{
  "required" : [ "changedInfo" ]
}'

That is obviously incorrect - as there is no VendorExtension defined in the swagger/declarations

openapi-generator version

6.2.1

OpenAPI declaration file content or url

The swagger (details given below) is an OpenApi 3.0 compliant one, and is available publicly: https://forge.etsi.org/rep/nfv/SOL002-SOL003/-/blob/v4.3.1/src/SOL003/VNFLifecycleManagement/VNFLifecycleManagement.yaml which refers to: https://forge.etsi.org/rep/nfv/SOL002-SOL003/-/blob/v4.3.1/src/SOL003/VNFLifecycleManagement/definitions/SOL003VNFLifecycleManagement_def.yaml

Look for "VnfLcmOpOcc"

Command line used for generation

Used maven plugin for generation:

         <plugin>
                <groupId>org.openapitools</groupId>
                <artifactId>openapi-generator-maven-plugin</artifactId>
                <version>6.2.1</version>
                <executions>
                    <execution>
                        <id>nfv-r431-vnfm-vnflcm</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <!-- COPY THE SWAGGER FROM THE ETSI FORGE LINK ABOVE AND PROVIDE THE PATH HERE: -->
                            <inputSpec>/.../VNFLifecycleManagement.yaml</inputSpec>
                            <apiPackage>nfvm.r431.vnfm.vnflcm</apiPackage>
                            <modelPackage>nfvm.r431.vnfm.vnflcm.model</modelPackage>
                            <library>spring-boot</library>
                            <skipValidateSpec>false</skipValidateSpec>
                            <generatorName>spring</generatorName>
                            <verbose>false</verbose>
                            <skipOverwrite>false</skipOverwrite>
                            <output>src/main/generated</output>
                            <generateSupportingFiles>true</generateSupportingFiles>
                            <supportingFilesToGenerate>ApiUtil.java</supportingFilesToGenerate>
                            <configOptions>
                                <delegatePattern>true</delegatePattern>
                                <sourceFolder>java</sourceFolder>
                                <skipOverwrite>true</skipOverwrite>
                                <interfaceOnly>true</interfaceOnly>
                            </configOptions>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
Steps to reproduce

Copy the swagger from ETSI forge locally, and use the Maven plugin to invoke the generator. And take a look at the generated class VnfLcmOpOcc - which is INCORRECT - a blank interface.

Related issues/PRs
Suggest a fix/enhancement

I am not sure why the generator makes VendorExtension.x-is-one-of-interface=true.

hkecho commented 1 year ago

You can add <useOneOfInterfaces>false</useOneOfInterfaces> in <configOptions> block, after that it will generate a class.

bruunand commented 1 year ago

Facing the same issue. useOneOfInterfaces makes no difference for me. Did you find a solution @sujeet-banerjee?

sujeet-banerjee commented 2 weeks ago

Facing the same issue. useOneOfInterfaces makes no difference for me. Did you find a solution @sujeet-banerjee?

Nope. For our purpose we have implemented a workaround. Alternatively, you could try to hack around the mustache templates (but I had not luck, nonetheless, I did not go ahead further that route)