Skip to content

Commit

Permalink
Support discriminator mappings for polymorphism (#830)
Browse files Browse the repository at this point in the history
  • Loading branch information
brice-laurencin authored Oct 27, 2024
1 parent 0b8a6d6 commit 6dccf8e
Show file tree
Hide file tree
Showing 5 changed files with 302 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{@org.openapitools.codegen.CodegenModel m}
{#if withXml}
{#else}
import com.fasterxml.jackson.annotation.JsonProperty;
Expand All @@ -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}
Expand Down Expand Up @@ -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/}
}
}
97 changes: 97 additions & 0 deletions client/integration-tests/polymorphism/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-openapi-generator-integration-tests</artifactId>
<groupId>io.quarkiverse.openapi.generator</groupId>
<version>3.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-openapi-generator-it-polymorphism</artifactId>
<name>Quarkus - Openapi Generator - Integration Tests - Polymorphism</name>

<dependencies>
<dependency>
<groupId>io.quarkiverse.openapi.generator</groupId>
<artifactId>quarkus-openapi-generator</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native-image</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${native.surefire.skip}</skipTests>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>
${project.build.directory}/${project.build.finalName}-runner
</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager
</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -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<String, String> 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();
}
}
}
}
1 change: 1 addition & 0 deletions client/integration-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<module>mutiny-return-response</module>
<module>open-api-normalizer</module>
<module>part-filename</module>
<module>polymorphism</module>
<module>return-response</module>
<module>security</module>
<module>simple</module>
Expand Down

0 comments on commit 6dccf8e

Please sign in to comment.