diff --git a/client/deployment/src/main/resources/templates/libraries/microprofile/pojo.qute b/client/deployment/src/main/resources/templates/libraries/microprofile/pojo.qute index 8a0c4ec3..4110882b 100644 --- a/client/deployment/src/main/resources/templates/libraries/microprofile/pojo.qute +++ b/client/deployment/src/main/resources/templates/libraries/microprofile/pojo.qute @@ -7,7 +7,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; **/ {/if} {#include additionalModelTypeAnnotations.qute m=m/} -{#if m.discriminator && m.discriminator.mappedModels && !m.discriminator.mappedModels.empty} +{#if m.discriminator && m.discriminator.mappedModels && !m.discriminator.mappedModels.empty && m.children} @com.fasterxml.jackson.annotation.JsonIgnoreProperties( value = "{m.discriminator.propertyBaseName}", // ignore manually set {m.discriminator.propertyBaseName}, it will be automatically generated by Jackson during serialization allowSetters = true // allows the {m.discriminator.propertyBaseName} to be set during deserialization diff --git a/client/deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapperTest.java b/client/deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapperTest.java index 9702518c..f354135b 100644 --- a/client/deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapperTest.java +++ b/client/deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapperTest.java @@ -84,8 +84,13 @@ void verifyOAuthDuplicateAnnotationOnCompositeAuthProvider() throws URISyntaxExc assertThat(oauthAnnotationsCount).isEqualTo(1); } + /** + * If the specification component has `oneOf` specified instead of `allOf`, the inner generator won't create a hierarchy of + * classes. + * In this situation, we can't generate the `JsonSubTypes` annotations. + */ @Test - void verifyDiscriminatorGeneration() throws java.net.URISyntaxException, FileNotFoundException { + void verifyOneOfDiscriminatorGeneration() throws java.net.URISyntaxException, FileNotFoundException { OpenApiClientGeneratorWrapper generatorWrapper = createGeneratorWrapper("issue-852.json"); final List generatedFiles = generatorWrapper.generate("org.issue852"); @@ -96,6 +101,30 @@ void verifyDiscriminatorGeneration() throws java.net.URISyntaxException, FileNot .filter(f -> f.getName().endsWith("PostRevisionForDocumentRequest.java")).findFirst(); assertThat(classWithDiscriminator).isPresent(); + final CompilationUnit compilationUnit = StaticJavaParser.parse(classWithDiscriminator.orElseThrow()); + assertThat(compilationUnit.findFirst(ClassOrInterfaceDeclaration.class) + .flatMap(first -> first.getAnnotationByClass(com.fasterxml.jackson.annotation.JsonSubTypes.class))) + .isNotPresent(); + } + + /** + * Only generates `JsonSubTypes` annotations in case the class has children, otherwise skip since Jackson will complain in + * runtime. + * The file issue-1022.json is a classic example of a spec with allOf to denote how the Java POJO should be and how Jackson + * would serialize. + */ + @Test + void verifyAllOfDiscriminatorGeneration() throws java.net.URISyntaxException, FileNotFoundException { + OpenApiClientGeneratorWrapper generatorWrapper = createGeneratorWrapper("issue-1022.json"); + final List generatedFiles = generatorWrapper.generate("org.issue1022"); + + assertNotNull(generatedFiles); + assertFalse(generatedFiles.isEmpty()); + + final Optional classWithDiscriminator = generatedFiles.stream() + .filter(f -> f.getName().startsWith("Thing.java")).findFirst(); + assertThat(classWithDiscriminator).isPresent(); + final CompilationUnit compilationUnit = StaticJavaParser.parse(classWithDiscriminator.orElseThrow()); assertThat(compilationUnit.findFirst(ClassOrInterfaceDeclaration.class) .flatMap(first -> first.getAnnotationByClass(com.fasterxml.jackson.annotation.JsonSubTypes.class))) diff --git a/client/deployment/src/test/resources/openapi/issue-1022.json b/client/deployment/src/test/resources/openapi/issue-1022.json new file mode 100644 index 00000000..3d7c6e95 --- /dev/null +++ b/client/deployment/src/test/resources/openapi/issue-1022.json @@ -0,0 +1,118 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "tuto API", + "version": "1.0.0-SNAPSHOT" + }, + "servers": [ + { + "url": "http://localhost:8080", + "description": "Auto generated value" + }, + { + "url": "http://0.0.0.0:8080", + "description": "Auto generated value" + } + ], + "paths": { + "/": { + "get": { + "tags": [ + "Default" + ], + "operationId": "get", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Data" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Data": { + "required": [ + "things" + ], + "type": "object", + "properties": { + "things": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Thing" + }, + "anyOf": [ + { + "$ref": "#/components/schemas/SomeThing" + }, + { + "$ref": "#/components/schemas/OtherThing" + } + ] + } + } + }, + "OtherThing": { + "description": "Other thing", + "required": [ + "other" + ], + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/Thing" + } + ], + "properties": { + "other": { + "type": "string" + } + } + }, + "SomeThing": { + "description": "Some thing", + "required": [ + "some" + ], + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/Thing" + } + ], + "properties": { + "some": { + "type": "string" + } + } + }, + "Thing": { + "description": "Thing", + "required": [ + "thing" + ], + "type": "object", + "properties": { + "thing": { + "type": "string" + } + }, + "discriminator": { + "propertyName": "@type", + "mapping": { + "SomeThing": "#/components/schemas/SomeThing", + "OtherThing": "#/components/schemas/OtherThing" + } + } + } + } + } +} diff --git a/docs/modules/ROOT/pages/includes/quarkus-openapi-generator-server_quarkus.openapi.adoc b/docs/modules/ROOT/pages/includes/quarkus-openapi-generator-server_quarkus.openapi.adoc new file mode 100644 index 00000000..8410f0a8 --- /dev/null +++ b/docs/modules/ROOT/pages/includes/quarkus-openapi-generator-server_quarkus.openapi.adoc @@ -0,0 +1,13 @@ +[.configuration-legend] +icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime +[.configuration-reference.searchable, cols="80,.^10,.^10"] +|=== + +h|[.header-title]##Configuration property## +h|Type +h|Default + +3+|No configuration properties found. + +|=== +