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 56d3e371..a8662e81 100644 --- a/client/deployment/src/main/resources/templates/libraries/microprofile/pojo.qute +++ b/client/deployment/src/main/resources/templates/libraries/microprofile/pojo.qute @@ -1,3 +1,4 @@ +{@org.openapitools.codegen.CodegenModel m} {#if withXml} {#else} import com.fasterxml.jackson.annotation.JsonProperty; @@ -20,6 +21,14 @@ import com.fasterxml.jackson.annotation.JsonProperty; @com.fasterxml.jackson.annotation.JsonIgnoreProperties(ignoreUnknown = true) {/if} {#include additionalModelTypeAnnotations.qute m=m/} +{#if m.discriminator && m.discriminator.mappedModels && !m.discriminator.mappedModels.empty} +@com.fasterxml.jackson.annotation.JsonTypeInfo(use = com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME, include = com.fasterxml.jackson.annotation.JsonTypeInfo.As.EXISTING_PROPERTY, property = "{m.discriminator.propertyBaseName}") +@com.fasterxml.jackson.annotation.JsonSubTypes({ +{#for child in m.discriminator.mappedModels} + @com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = {child.model.classname}.class, name = "{child.mappingName}"), +{/for} +}) +{/if} public class {m.classname} {#if m.parent}extends {m.parent}{/if}{#if m.serializableModel} implements java.io.Serializable{/if} { {#for v in m.vars} @@ -151,4 +160,4 @@ public class {m.classname} {#if m.parent}extends {m.parent}{/if}{#if m.serializa } {#include pojoQueryParam.qute m=m.model withXml=withXml codegen=classes-codegen package=modelPackage/} -} \ No newline at end of file +} diff --git a/client/integration-tests/polymorphism/pom.xml b/client/integration-tests/polymorphism/pom.xml new file mode 100644 index 00000000..fe79e455 --- /dev/null +++ b/client/integration-tests/polymorphism/pom.xml @@ -0,0 +1,97 @@ + + + + quarkus-openapi-generator-integration-tests + io.quarkiverse.openapi.generator + 3.0.0-SNAPSHOT + + 4.0.0 + + quarkus-openapi-generator-it-polymorphism + Quarkus - Openapi Generator - Integration Tests - Polymorphism + + + + io.quarkiverse.openapi.generator + quarkus-openapi-generator + + + io.quarkus + quarkus-junit5 + test + + + com.github.tomakehurst + wiremock-jre8 + test + + + org.assertj + assertj-core + test + + + + + + io.quarkus + quarkus-maven-plugin + true + + + + build + generate-code + generate-code-tests + + + + + + + + + native-image + + + native + + + + + + maven-surefire-plugin + + ${native.surefire.skip} + + + + maven-failsafe-plugin + + + + integration-test + verify + + + + + ${project.build.directory}/${project.build.finalName}-runner + + org.jboss.logmanager.LogManager + + ${maven.home} + + + + + + + + + native + + + + diff --git a/client/integration-tests/polymorphism/src/main/openapi/polymorphism.json b/client/integration-tests/polymorphism/src/main/openapi/polymorphism.json new file mode 100644 index 00000000..3d7c6e95 --- /dev/null +++ b/client/integration-tests/polymorphism/src/main/openapi/polymorphism.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/client/integration-tests/polymorphism/src/test/java/io/quarkiverse/openapi/generator/it/PolymorphismTest.java b/client/integration-tests/polymorphism/src/test/java/io/quarkiverse/openapi/generator/it/PolymorphismTest.java new file mode 100644 index 00000000..fc527cd2 --- /dev/null +++ b/client/integration-tests/polymorphism/src/test/java/io/quarkiverse/openapi/generator/it/PolymorphismTest.java @@ -0,0 +1,76 @@ +package io.quarkiverse.openapi.generator.it; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + +import java.util.Collections; +import java.util.Map; + +import jakarta.inject.Inject; + +import org.eclipse.microprofile.rest.client.inject.RestClient; +import org.junit.jupiter.api.Test; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +@QuarkusTestResource(PolymorphismTest.MockServer.class) +class PolymorphismTest { + + @RestClient + @Inject + org.openapi.quarkus.polymorphism_json.api.DefaultApi api; + + @Test + void apiIsBeingGenerated() { + + org.openapi.quarkus.polymorphism_json.model.Data data = api.get(); + + data.getThings() + .forEach(it -> assertInstanceOf(org.openapi.quarkus.polymorphism_json.model.Thing.class, it)); + assertInstanceOf(org.openapi.quarkus.polymorphism_json.model.SomeThing.class, data.getThings().get(0)); + assertInstanceOf(org.openapi.quarkus.polymorphism_json.model.OtherThing.class, data.getThings().get(1)); + } + + public static class MockServer implements QuarkusTestResourceLifecycleManager { + + private WireMockServer wireMockServer; + + @Override + public Map start() { + configureWiremockServer(); + return Collections.singletonMap("org.openapi.quarkus.polymorphism_json.api.DefaultApi/mp-rest/url", + wireMockServer.baseUrl()); + } + + private void configureWiremockServer() { + var wireMockConfiguration = WireMockConfiguration.wireMockConfig() + .extensions(new ResponseTemplateTransformer(false)).dynamicPort(); + wireMockServer = new WireMockServer(wireMockConfiguration); + wireMockServer.start(); + + wireMockServer.stubFor(get(urlEqualTo("/")) + .willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody( + "{\"things\":[{\"@type\":\"SomeThing\",\"thing\":\"thing\",\"some\":\"some\"},{\"@type\":\"OtherThing\",\"thing\":\"thing\",\"other\":\"other\"}]}") + .withTransformers("response-template"))); + } + + @Override + public void stop() { + if (wireMockServer != null) { + wireMockServer.stop(); + } + } + } +} diff --git a/client/integration-tests/pom.xml b/client/integration-tests/pom.xml index 45687124..8c2d96ba 100644 --- a/client/integration-tests/pom.xml +++ b/client/integration-tests/pom.xml @@ -31,6 +31,7 @@ mutiny-return-response open-api-normalizer part-filename + polymorphism return-response security simple