[Kotlin] Add a new additional property to configure Jackson's failOnUnknownProperties (#19506)

* [Kotlin] Add a new additional property to configure Jackson's `failOnUnknownProperties`

Default to false

* [Kotlin] Unconditionally import `com.fasterxml.jackson.databind.DeserializationFeature`

* [Kotlin] Refactor and add test
This commit is contained in:
Eric 2024-09-16 11:59:17 +02:00 committed by GitHub
parent 0c5142a6f6
commit 425aa7db44
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 52 additions and 2 deletions

View File

@ -25,6 +25,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|collectionType|Option. Collection type to use|<dl><dt>**array**</dt><dd>kotlin.Array</dd><dt>**list**</dt><dd>kotlin.collections.List</dd></dl>|list|
|dateLibrary|Option. Date library to use|<dl><dt>**threetenbp-localdatetime**</dt><dd>Threetenbp - Backport of JSR310 (jvm only, for legacy app only)</dd><dt>**kotlinx-datetime**</dt><dd>kotlinx-datetime (preferred for multiplatform)</dd><dt>**string**</dt><dd>String</dd><dt>**java8-localdatetime**</dt><dd>Java 8 native JSR310 (jvm only, for legacy app only)</dd><dt>**java8**</dt><dd>Java 8 native JSR310 (jvm only, preferred for jdk 1.8+)</dd><dt>**threetenbp**</dt><dd>Threetenbp - Backport of JSR310 (jvm only, preferred for jdk &lt; 1.8)</dd></dl>|java8|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |original|
|failOnUnknownProperties|Fail Jackson de-serialization on unknown properties| |false|
|generateOneOfAnyOfWrappers|Generate oneOf, anyOf schemas as wrappers.| |false|
|generateRoomModels|Generate Android Room database models in addition to API models (JVM Volley library only)| |false|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|

View File

@ -85,6 +85,7 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
public static final String DATE_LIBRARY = "dateLibrary";
public static final String REQUEST_DATE_CONVERTER = "requestDateConverter";
public static final String COLLECTION_TYPE = "collectionType";
public static final String FAIL_ON_UNKNOWN_PROPERTIES = "failOnUnknownProperties";
public static final String MOSHI_CODE_GEN = "moshiCodeGen";
@ -108,6 +109,7 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
@Setter protected String roomModelPackage = "";
@Setter protected boolean omitGradleWrapper = false;
@Setter protected boolean generateOneOfAnyOfWrappers = true;
@Getter @Setter protected boolean failOnUnknownProperties = false;
protected String authFolder;
@ -259,6 +261,7 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
cliOptions.add(CliOption.newBoolean(IDEA, "Add IntellJ Idea plugin and mark Kotlin main and test folders as source folders."));
cliOptions.add(CliOption.newBoolean(MOSHI_CODE_GEN, "Whether to enable codegen with the Moshi library. Refer to the [official Moshi doc](https://github.com/square/moshi#codegen) for more info."));
cliOptions.add(CliOption.newBoolean(FAIL_ON_UNKNOWN_PROPERTIES, "Fail Jackson de-serialization on unknown properties", false));
cliOptions.add(CliOption.newBoolean(NULLABLE_RETURN_TYPE, "Nullable return type"));
@ -438,6 +441,13 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
setGenerateOneOfAnyOfWrappers(Boolean.parseBoolean(additionalProperties.get(GENERATE_ONEOF_ANYOF_WRAPPERS).toString()));
}
if (additionalProperties.containsKey(FAIL_ON_UNKNOWN_PROPERTIES)) {
setFailOnUnknownProperties(Boolean.parseBoolean(additionalProperties.get(FAIL_ON_UNKNOWN_PROPERTIES).toString()));
} else {
additionalProperties.put(FAIL_ON_UNKNOWN_PROPERTIES, false);
setFailOnUnknownProperties(false);
}
commonSupportingFiles();
switch (getLibrary()) {

View File

@ -28,9 +28,7 @@ import kotlinx.datetime.Instant
import java.util.UUID
{{/gson}}
{{#jackson}}
{{#enumUnknownDefaultCase}}
import com.fasterxml.jackson.databind.DeserializationFeature
{{/enumUnknownDefaultCase}}
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.annotation.JsonInclude
@ -111,6 +109,7 @@ import java.util.concurrent.atomic.AtomicLong
.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, true)
{{/enumUnknownDefaultCase}}
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, {{failOnUnknownProperties}})
{{/jackson}}
{{#kotlinx_serialization}}
@Deprecated("Use Serializer.kotlinxSerializationAdapters instead", replaceWith = ReplaceWith("Serializer.kotlinxSerializationAdapters"))

View File

@ -34,6 +34,7 @@ import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.languages.KotlinClientCodegen;
import org.openapitools.codegen.testutils.ConfigAssert;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@ -406,6 +407,32 @@ public class KotlinClientCodegenModelTest {
TestUtils.assertFileNotExists(Paths.get(path, "gradle", "wrapper", "gradle-wrapper.jar"));
}
@Test
public void testFailOnUnknownPropertiesAdditionalProperty() {
final KotlinClientCodegen codegen = new KotlinClientCodegen();
// Default case, nothing provided
codegen.processOpts();
ConfigAssert configAssert = new ConfigAssert(codegen.additionalProperties());
// Default to false
configAssert.assertValue(KotlinClientCodegen.FAIL_ON_UNKNOWN_PROPERTIES, codegen::isFailOnUnknownProperties, Boolean.FALSE);
// Provide true
codegen.additionalProperties().put(KotlinClientCodegen.FAIL_ON_UNKNOWN_PROPERTIES, true);
codegen.processOpts();
// Should be true
configAssert.assertValue(KotlinClientCodegen.FAIL_ON_UNKNOWN_PROPERTIES, codegen::isFailOnUnknownProperties, Boolean.TRUE);
// Provide false
codegen.additionalProperties().put(KotlinClientCodegen.FAIL_ON_UNKNOWN_PROPERTIES, false);
codegen.processOpts();
// Should be false
configAssert.assertValue(KotlinClientCodegen.FAIL_ON_UNKNOWN_PROPERTIES, codegen::isFailOnUnknownProperties, Boolean.FALSE);
}
private static class ModelNameTest {
private final String expectedName;
private final String expectedClassName;

View File

@ -13,4 +13,5 @@ object Serializer {
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, true)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
}

View File

@ -13,4 +13,5 @@ object Serializer {
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, true)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
}

View File

@ -13,4 +13,5 @@ object Serializer {
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, true)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
}

View File

@ -13,4 +13,5 @@ object Serializer {
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, true)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
}

View File

@ -13,4 +13,5 @@ object Serializer {
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, true)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
}

View File

@ -13,4 +13,5 @@ object Serializer {
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, true)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
}

View File

@ -13,4 +13,5 @@ object Serializer {
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, true)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
}

View File

@ -1,5 +1,6 @@
package org.openapitools.client.infrastructure
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.annotation.JsonInclude
@ -11,4 +12,5 @@ object Serializer {
.findAndRegisterModules()
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
}

View File

@ -1,5 +1,6 @@
package org.openapitools.client.infrastructure
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.annotation.JsonInclude
@ -11,4 +12,5 @@ object Serializer {
.findAndRegisterModules()
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
}

View File

@ -1,5 +1,6 @@
package org.openapitools.client.infrastructure
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.annotation.JsonInclude
@ -11,4 +12,5 @@ object Serializer {
.findAndRegisterModules()
.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
}