From 8ffbebd9a27fa5ebc0c14e2b441fada933e3ee2b Mon Sep 17 00:00:00 2001 From: Ilya Taratukhin Date: Tue, 10 Sep 2024 17:36:15 +0200 Subject: [PATCH 1/2] chore: use shared commitlint config --- commitlint.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commitlint.config.js b/commitlint.config.js index 422b1944..ca894a01 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -1 +1 @@ -module.exports = { extends: ['@commitlint/config-conventional'] }; +module.exports = { extends: ['@fingerprintjs/commit-lint-dx-team'] }; From 979b800c89d6ff9a44325043f99ec7fb7040f94a Mon Sep 17 00:00:00 2001 From: Ilya Taratukhin Date: Tue, 10 Sep 2024 17:36:42 +0200 Subject: [PATCH 2/2] feat: don't use `jackson-databind-nullable` to fix serialization problems with `Jackson` default configuration --- gradle/libs.versions.toml | 4 +- sdk/sdk.gradle.kts | 4 +- .../model/RawDeviceAttributesResultValue.java | 41 +++----------- .../main/java/com/fingerprint/sdk/JSON.java | 3 - .../com/fingerprint/SerializationTest.java | 56 +++++++++++++++++++ .../fingerprint/api/FingerprintApiTest.java | 5 -- 6 files changed, 68 insertions(+), 45 deletions(-) create mode 100644 sdk/src/test/java/com/fingerprint/SerializationTest.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dc11a971..e7ab784a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,5 @@ [versions] jackson = "2.17.2" -jackson-databind-nullable = "0.2.6" jakarta-annotation-api = "2.0.0" jersey = "3.1.7" junit = "5.10.2" @@ -12,7 +11,6 @@ swagger-annotations = "2.2.22" jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations", version.ref = "jackson" } jackson-core = { module = "com.fasterxml.jackson.core:jackson-core", version.ref = "jackson" } jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } -jackson-databind-nullable = { module = "org.openapitools:jackson-databind-nullable", version.ref = "jackson-databind-nullable" } jackson-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" } jakarta-annotation-api = { module = "jakarta.annotation:jakarta.annotation-api", version.ref = "jakarta-annotation-api" } jersey-apache-connector = { module = "org.glassfish.jersey.connectors:jersey-apache-connector", version.ref = "jersey" } @@ -26,4 +24,4 @@ mockito = { module = "org.mockito:mockito-core", version.ref = "mockito" } swagger-annotations = { module = "io.swagger.core.v3:swagger-annotations", version.ref = "swagger-annotations" } [plugins] -openapi-generator = { id = "org.openapi.generator", version.ref = "openapi" } \ No newline at end of file +openapi-generator = { id = "org.openapi.generator", version.ref = "openapi" } diff --git a/sdk/sdk.gradle.kts b/sdk/sdk.gradle.kts index 20a58a8f..d2f07a47 100644 --- a/sdk/sdk.gradle.kts +++ b/sdk/sdk.gradle.kts @@ -35,7 +35,6 @@ dependencies { api(libs.jackson.core) api(libs.jackson.annotations) api(libs.jackson.databind) - api(libs.jackson.databind.nullable) api(libs.jackson.jsr310) api(libs.jakarta.annotation.api) testImplementation(libs.junit.jupiter.api) @@ -68,6 +67,7 @@ openApiGenerate { gitRepoId.set("fingerprint-pro-server-api-java-sdk") gitUserId.set("fingerprintjs") configOptions.put("hideGenerationTimestamp", "true") + configOptions.put("openApiNullable", "false") } tasks.register("removeDocs") { @@ -143,4 +143,4 @@ tasks.test { tasks.jar { archiveBaseName = "fingerprint-pro-server-api-sdk" -} \ No newline at end of file +} diff --git a/sdk/src/main/java/com/fingerprint/model/RawDeviceAttributesResultValue.java b/sdk/src/main/java/com/fingerprint/model/RawDeviceAttributesResultValue.java index ad1e2cdb..46809fe6 100644 --- a/sdk/src/main/java/com/fingerprint/model/RawDeviceAttributesResultValue.java +++ b/sdk/src/main/java/com/fingerprint/model/RawDeviceAttributesResultValue.java @@ -8,10 +8,6 @@ import com.fasterxml.jackson.annotation.JsonValue; import com.fingerprint.model.Error; import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; -import com.fasterxml.jackson.annotation.JsonIgnore; -import org.openapitools.jackson.nullable.JsonNullable; -import java.util.NoSuchElementException; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fingerprint.sdk.JSON; import io.swagger.v3.oas.annotations.media.Schema; @@ -32,7 +28,7 @@ public class RawDeviceAttributesResultValue { private Error error; public static final String JSON_PROPERTY_VALUE = "value"; - private JsonNullable value = JsonNullable.of(null); + private Object value = null; public RawDeviceAttributesResultValue() { } @@ -64,7 +60,7 @@ public void setError(Error error) { public RawDeviceAttributesResultValue value(Object value) { - this.value = JsonNullable.of(value); + this.value = value; return this; } @@ -74,26 +70,18 @@ public RawDeviceAttributesResultValue value(Object value) { **/ @jakarta.annotation.Nullable @Schema(description = "") - @JsonIgnore - - public Object getValue() { - return value.orElse(null); - } - @JsonProperty(JSON_PROPERTY_VALUE) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public JsonNullable getValue_JsonNullable() { + public Object getValue() { return value; } - - @JsonProperty(JSON_PROPERTY_VALUE) - public void setValue_JsonNullable(JsonNullable value) { - this.value = value; - } + + @JsonProperty(JSON_PROPERTY_VALUE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) public void setValue(Object value) { - this.value = JsonNullable.of(value); + this.value = value; } @@ -110,23 +98,12 @@ public boolean equals(Object o) { } RawDeviceAttributesResultValue rawDeviceAttributesResultValue = (RawDeviceAttributesResultValue) o; return Objects.equals(this.error, rawDeviceAttributesResultValue.error) && - equalsNullable(this.value, rawDeviceAttributesResultValue.value); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + Objects.equals(this.value, rawDeviceAttributesResultValue.value); } @Override public int hashCode() { - return Objects.hash(error, hashCodeNullable(value)); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + return Objects.hash(error, value); } @Override diff --git a/sdk/src/main/java/com/fingerprint/sdk/JSON.java b/sdk/src/main/java/com/fingerprint/sdk/JSON.java index 4c53b6dc..26b26ee3 100644 --- a/sdk/src/main/java/com/fingerprint/sdk/JSON.java +++ b/sdk/src/main/java/com/fingerprint/sdk/JSON.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.json.JsonMapper; -import org.openapitools.jackson.nullable.JsonNullableModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fingerprint.model.*; @@ -30,8 +29,6 @@ public JSON() { mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); mapper.setDateFormat(new RFC3339DateFormat()); mapper.registerModule(new JavaTimeModule()); - JsonNullableModule jnm = new JsonNullableModule(); - mapper.registerModule(jnm); } /** diff --git a/sdk/src/test/java/com/fingerprint/SerializationTest.java b/sdk/src/test/java/com/fingerprint/SerializationTest.java new file mode 100644 index 00000000..1cccce81 --- /dev/null +++ b/sdk/src/test/java/com/fingerprint/SerializationTest.java @@ -0,0 +1,56 @@ +package com.fingerprint; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fingerprint.model.EventResponse; +import com.fingerprint.model.RawDeviceAttributesResultValue; +import com.fingerprint.model.SignalResponseRawDeviceAttributes; +import com.fingerprint.sdk.ApiException; +import com.fingerprint.sdk.JSON; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class SerializationTest { + + private InputStream getFileAsIOStream(final String fileName) { + InputStream ioStream = this.getClass() + .getClassLoader() + .getResourceAsStream(fileName); + + if (ioStream == null) { + throw new IllegalArgumentException(fileName + " is not found"); + } + return ioStream; + } + + private static ObjectMapper getMapper() { + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new JavaTimeModule()); + mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); +// mapper.configure(SerializationFeature.INDENT_OUTPUT, true); + return mapper; + } + + @Test + public void serializeRawDeviceAttributesTest() throws IOException { + ObjectMapper sdkObjectMapper = JSON.getDefault().getMapper(); + EventResponse eventResponse = sdkObjectMapper.readValue(getFileAsIOStream("mocks/get_event_200.json"), EventResponse.class); + + SignalResponseRawDeviceAttributes signalResponseRawDeviceAttributes = eventResponse.getProducts().getRawDeviceAttributes(); + String sdkResult = sdkObjectMapper.writeValueAsString(signalResponseRawDeviceAttributes); + + ObjectMapper springLikeObjectMapper = getMapper(); + String springResult = springLikeObjectMapper.writeValueAsString(signalResponseRawDeviceAttributes); + + assertTrue(sdkResult.contains("\"architecture\":{\"value\":127}")); + assertTrue(springResult.contains("\"architecture\":{\"error\":null,\"value\":127}")); + } +} diff --git a/sdk/src/test/java/com/fingerprint/api/FingerprintApiTest.java b/sdk/src/test/java/com/fingerprint/api/FingerprintApiTest.java index 708cf4f8..51fcab49 100644 --- a/sdk/src/test/java/com/fingerprint/api/FingerprintApiTest.java +++ b/sdk/src/test/java/com/fingerprint/api/FingerprintApiTest.java @@ -15,7 +15,6 @@ import org.junit.jupiter.api.TestInstance; import org.mockito.Mockito; -import org.openapitools.jackson.nullable.JsonNullableModule; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.when; @@ -69,8 +68,6 @@ private static ObjectMapper getMapper() { ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - JsonNullableModule jnm = new JsonNullableModule(); - mapper.registerModule(jnm); return mapper; } @@ -263,8 +260,6 @@ public void getVisitsTest() throws ApiException { public void webhookTest() throws Exception { ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - JsonNullableModule jnm = new JsonNullableModule(); - mapper.registerModule(jnm); WebhookVisit visit = mapper.readValue(getFileAsIOStream("mocks/webhook.json"), WebhookVisit.class);