Skip to content

Commit

Permalink
First draft to support unexpected enum values (#700)
Browse files Browse the repository at this point in the history
  • Loading branch information
brice-laurencin authored Jun 14, 2024
1 parent d0f8224 commit fe50799
Show file tree
Hide file tree
Showing 16 changed files with 346 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ public class CodegenConfig extends GlobalCodegenConfig {

public static final String API_PKG_SUFFIX = ".api";
public static final String MODEL_PKG_SUFFIX = ".model";

public static final String ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER_NAME_DEFAULT = "UNEXPECTED";
public static final String ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER_STRING_VALUE_DEFAULT = "unexpected";
// package visibility for unit tests
static final String BUILD_TIME_GLOBAL_PREFIX_FORMAT = "quarkus." + CODEGEN_TIME_CONFIG_PREFIX + ".%s";
static final String BUILD_TIME_SPEC_PREFIX_FORMAT = "quarkus." + CODEGEN_TIME_CONFIG_PREFIX + ".spec.%s";
Expand All @@ -46,6 +49,9 @@ public enum ConfigName {
SKIP_FORM_MODEL("skip-form-model"),
MUTINY("mutiny"),
ADDITIONAL_MODEL_TYPE_ANNOTATIONS("additional-model-type-annotations"),
ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER("additional-enum-type-unexpected-member"),
ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER_NAME("additional-enum-type-unexpected-member-name"),
ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER_STRING_VALUE("additional-enum-type-unexpected-member-string-value"),
ADDITIONAL_API_TYPE_ANNOTATIONS("additional-api-type-annotations"),
TYPE_MAPPINGS("type-mappings"),
IMPORT_MAPPINGS("import-mappings"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ public class CommonItemConfig {
@ConfigItem(name = "additional-model-type-annotations")
public Optional<String> additionalModelTypeAnnotations;

/**
* Defines if the enums should have an `UNEXPECTED` member to convey values that cannot be parsed. Default is
* <code>false</code>.
*/
@ConfigItem(name = "additional-enum-type-unexpected-member")
public Optional<Boolean> additionalEnumTypeUnexpectedMemberAnnotations;

/**
* The specified annotations will be added to the generated api files
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.quarkiverse.openapi.generator.deployment.codegen;

import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER_NAME_DEFAULT;
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER_STRING_VALUE_DEFAULT;
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.getGlobalConfigName;
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.getSanitizedFileName;
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.getSpecConfigName;
Expand Down Expand Up @@ -202,6 +204,21 @@ protected void generate(final Config config, final Path openApiFilePath, final P
getValues(config, openApiFilePath, CodegenConfig.ConfigName.ADDITIONAL_MODEL_TYPE_ANNOTATIONS, String.class)
.ifPresent(generator::withAdditionalModelTypeAnnotationsConfig);

generator.withAdditionalEnumTypeUnexpectedMemberConfig(
getValues(config, openApiFilePath, CodegenConfig.ConfigName.ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER,
Boolean.class)
.orElse(false));

generator.withAdditionalEnumTypeUnexpectedMemberNameConfig(
getValues(config, openApiFilePath, CodegenConfig.ConfigName.ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER_NAME,
String.class)
.orElse(ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER_NAME_DEFAULT));

generator.withAdditionalEnumTypeUnexpectedMemberStringValueConfig(
getValues(config, openApiFilePath, CodegenConfig.ConfigName.ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER_STRING_VALUE,
String.class)
.orElse(ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER_STRING_VALUE_DEFAULT));

getValues(config, openApiFilePath, CodegenConfig.ConfigName.ADDITIONAL_API_TYPE_ANNOTATIONS, String.class)
.ifPresent(generator::withAdditionalApiTypeAnnotationsConfig);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class QuteTemplatingEngineAdapter extends AbstractTemplatingEngineAdapter
public static final String IDENTIFIER = "qute";
public static final String[] INCLUDE_TEMPLATES = {
"additionalEnumTypeAnnotations.qute",
"additionalEnumTypeUnexpectedMember.qute",
"additionalModelTypeAnnotations.qute",
"beanValidation.qute",
"beanValidationCore.qute",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,26 @@ public OpenApiClientGeneratorWrapper withAdditionalModelTypeAnnotationsConfig(fi
return this;
}

public OpenApiClientGeneratorWrapper withAdditionalEnumTypeUnexpectedMemberConfig(
final Boolean additionalEnumTypeUnexpectedMember) {
this.configurator.addAdditionalProperty("additionalEnumTypeUnexpectedMember", additionalEnumTypeUnexpectedMember);
return this;
}

public OpenApiClientGeneratorWrapper withAdditionalEnumTypeUnexpectedMemberNameConfig(
final String additionalEnumTypeUnexpectedMemberName) {
this.configurator.addAdditionalProperty("additionalEnumTypeUnexpectedMemberName",
additionalEnumTypeUnexpectedMemberName);
return this;
}

public OpenApiClientGeneratorWrapper withAdditionalEnumTypeUnexpectedMemberStringValueConfig(
final String additionalEnumTypeUnexpectedMemberStringValue) {
this.configurator.addAdditionalProperty("additionalEnumTypeUnexpectedMemberStringValue",
additionalEnumTypeUnexpectedMemberStringValue);
return this;
}

/**
* Sets the global 'additionalApiTypeAnnotations' setting. If not set this setting will default to empty.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* Special value if the API response contains some new value not declared in this enum.
* You should react accordingly.
*/
{additionalEnumTypeUnexpectedMemberName}({#if e.isContainer}{e.items.dataType}{#else}{e.dataType}{/if}.valueOf("{additionalEnumTypeUnexpectedMemberStringValue}")){#if e.allowableValues},{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
{/if}
{#include additionalEnumTypeAnnotations.qute e=e /}public enum {e.enumName} {
{#if e.allowableValues}
{#if additionalEnumTypeUnexpectedMember}{#include additionalEnumTypeUnexpectedMember.qute e=e/}{/if}
{#if e.withXml}
{#for v in e.allowableValues.enumVars}@XmlEnumValue({#if v.isInteger || v.isDouble || v.isLong || v.isFloat}"{/if}{v.value}{#if v.isInteger || v.isDouble || v.isLong || v.isFloat}"{/if}) {v.name}({#if e.isEnum}{e.items.dataType}{#else}{e.dataType}{/if}.valueOf({v.value})){#if v_hasNext}, {#else}; {/if}{/for}
{#else}
Expand Down Expand Up @@ -37,6 +38,6 @@
return b;
}
}
{#if e.useNullForUnknownEnumValue}return null;{#else}throw new IllegalArgumentException("Unexpected value '" + v + "'");{/if}
{#if e.useNullForUnknownEnumValue}return null;{#else if additionalEnumTypeUnexpectedMember}return {additionalEnumTypeUnexpectedMemberName};{#else}throw new IllegalArgumentException("Unexpected value '" + v + "'");{/if}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import java.util.EnumSet;
@JsonIgnoreProperties(ignoreUnknown = true)
{#include additionalEnumTypeAnnotations.qute e=e/}public enum {#if e.datatypeWithEnum}{e.datatypeWithEnum}{#else}{e.classname}{/if} {
{#if e.allowableValues}
{#if additionalEnumTypeUnexpectedMember}{#include additionalEnumTypeUnexpectedMember.qute e=e/}{/if}
{#for v in e.allowableValues.enumVars}{v.name}({e.dataType}.valueOf({v.value})){#if v_hasNext}, {#else};{/if}{/for}
{/if}

Expand Down Expand Up @@ -38,6 +39,6 @@ import java.util.EnumSet;
return b;
}
}
{#if e.useNullForUnknownEnumValue}return null;{#else}throw new IllegalArgumentException("Unexpected value '" + text + "'");{/if}
{#if e.useNullForUnknownEnumValue}return null;{#else if additionalEnumTypeUnexpectedMember}return {additionalEnumTypeUnexpectedMemberName};{#else}throw new IllegalArgumentException("Unexpected value '" + text + "'");{/if}
}
}
}
95 changes: 95 additions & 0 deletions client/integration-tests/enum-unexpected/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?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-enum-unexpected</artifactId>
<name>Quarkus - Openapi Generator - Integration Tests - Enum Unexpected</name>
<description>Example project for OpenAPI with enum unexpected value</description>

<dependencies>
<dependency>
<groupId>io.quarkiverse.openapi.generator</groupId>
<artifactId>quarkus-openapi-generator</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</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>
</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,28 @@
openapi: 3.0.3
info:
title: echo
version: '1.0.0'
description: ""
paths:
/echo:
post:
summary: Echo
operationId: echo
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Echo'
components:
schemas:
Echo:
type: object
required:
- msgType
properties:
msgType:
type: string
enum:
- 'text'
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
openapi: 3.0.3
info:
title: echo
version: '1.0.0'
description: ""
paths:
/echo:
post:
summary: Echo
operationId: echo
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Echo'
components:
schemas:
Echo:
type: object
required:
- msgType
properties:
msgType:
type: string
enum:
- 'text'
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
quarkus.openapi-generator.codegen.spec.with_enum_unexpected_yaml.additional-enum-type-unexpected-member=true


quarkus.openapi-generator.codegen.spec.without_enum_unexpected_yaml.additional-enum-type-unexpected-member=false
Loading

0 comments on commit fe50799

Please sign in to comment.