From 054aa67d3415d02cb465b0160ba6dff1e2cc8210 Mon Sep 17 00:00:00 2001 From: Jorge Bornhausen Date: Fri, 18 Oct 2024 23:47:10 +0200 Subject: [PATCH] added json module --- README.md | 2 + pom.xml | 1 + quarkus-json-service/pom.xml | 22 +++++ .../quarkus/commons/json/JsonService.java | 13 +++ .../quarkus/commons/json/JsonServiceImpl.java | 48 +++++++++++ .../commons/json/JsonServiceImplTest.java | 80 +++++++++++++++++++ 6 files changed, 166 insertions(+) create mode 100644 quarkus-json-service/pom.xml create mode 100644 quarkus-json-service/src/main/java/ch/phoenixtechnologies/quarkus/commons/json/JsonService.java create mode 100644 quarkus-json-service/src/main/java/ch/phoenixtechnologies/quarkus/commons/json/JsonServiceImpl.java create mode 100644 quarkus-json-service/src/test/java/ch/phoenixtechnologies/quarkus/commons/json/JsonServiceImplTest.java diff --git a/README.md b/README.md index b685699..10348ab 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ that can be used by Quarkus applications. The modules are: * `quarkus-clock-service` +* `quarkus-json-service` +* `quarkus-message-digest-service` * `quarkus-random-number-generator` * `quarkus-uuid-generator` diff --git a/pom.xml b/pom.xml index 10c2e5a..12df92f 100644 --- a/pom.xml +++ b/pom.xml @@ -10,6 +10,7 @@ quarkus-clock-service + quarkus-json-service quarkus-message-digest-service quarkus-random-number-generator quarkus-uuid-generator diff --git a/quarkus-json-service/pom.xml b/quarkus-json-service/pom.xml new file mode 100644 index 0000000..5a60e5c --- /dev/null +++ b/quarkus-json-service/pom.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + + ch.phoenixtechnologies.quarkus + quarkus-commons + 0.1.0-SNAPSHOT + + + quarkus-json-service + jar + + + + io.quarkus + quarkus-jackson + + + diff --git a/quarkus-json-service/src/main/java/ch/phoenixtechnologies/quarkus/commons/json/JsonService.java b/quarkus-json-service/src/main/java/ch/phoenixtechnologies/quarkus/commons/json/JsonService.java new file mode 100644 index 0000000..9570ae7 --- /dev/null +++ b/quarkus-json-service/src/main/java/ch/phoenixtechnologies/quarkus/commons/json/JsonService.java @@ -0,0 +1,13 @@ +package ch.phoenixtechnologies.quarkus.commons.json; + +import com.fasterxml.jackson.core.type.TypeReference; + +public interface JsonService { + + String toJson(Object object); + + T fromJson(String json, Class clazz); + + T fromJson(String json, TypeReference typeReference); + +} diff --git a/quarkus-json-service/src/main/java/ch/phoenixtechnologies/quarkus/commons/json/JsonServiceImpl.java b/quarkus-json-service/src/main/java/ch/phoenixtechnologies/quarkus/commons/json/JsonServiceImpl.java new file mode 100644 index 0000000..32f2b41 --- /dev/null +++ b/quarkus-json-service/src/main/java/ch/phoenixtechnologies/quarkus/commons/json/JsonServiceImpl.java @@ -0,0 +1,48 @@ +package ch.phoenixtechnologies.quarkus.commons.json; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.quarkus.arc.DefaultBean; +import jakarta.enterprise.context.ApplicationScoped; + +@DefaultBean +@ApplicationScoped +class JsonServiceImpl implements JsonService { + + private final ObjectMapper objectMapper; + + JsonServiceImpl(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public String toJson(Object object) { + try { + return objectMapper.writeValueAsString(object); + } catch (JsonProcessingException e) { + throw new IllegalArgumentException("Unable to write object as json String: " + object, e); + } + } + + @Override + public T fromJson(String json, Class clazz) { + try { + return objectMapper.readValue(json, clazz); + } catch (JsonProcessingException e) { + throw new IllegalArgumentException("Unable to read object of class [" + clazz.getName() + + "] from json String: " + json, e); + } + + } + + @Override + public T fromJson(String json, TypeReference typeReference) { + try { + return objectMapper.readValue(json, typeReference); + } catch (JsonProcessingException e) { + throw new IllegalArgumentException("Unable to read object of type [" + typeReference.getType().getTypeName() + + "] from json String: " + json, e); + } + } +} diff --git a/quarkus-json-service/src/test/java/ch/phoenixtechnologies/quarkus/commons/json/JsonServiceImplTest.java b/quarkus-json-service/src/test/java/ch/phoenixtechnologies/quarkus/commons/json/JsonServiceImplTest.java new file mode 100644 index 0000000..a9a388e --- /dev/null +++ b/quarkus-json-service/src/test/java/ch/phoenixtechnologies/quarkus/commons/json/JsonServiceImplTest.java @@ -0,0 +1,80 @@ +package ch.phoenixtechnologies.quarkus.commons.json; + +import com.fasterxml.jackson.core.type.TypeReference; +import io.quarkus.test.junit.QuarkusTest; +import jakarta.inject.Inject; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@QuarkusTest +class JsonServiceImplTest { + + public static final TypeReference> TYPE_REFERENCE = new TypeReference<>() { + }; + + record TestRecord(String name, int age) { + } + + @Inject + JsonServiceImpl jsonService; + + @Test + void toJson() { + var expected = "{\"name\":\"John Doe\",\"age\":30}"; + + var actual = jsonService.toJson(new TestRecord("John Doe", 30)); + + assertThat(actual) + .as("Json should match expected value") + .isEqualTo(expected); + } + + @Test + void fromJsonWithClass() { + var json = "{\"name\":\"John Doe\",\"age\":30}"; + var expected = new TestRecord("John Doe", 30); + + var actual = jsonService.fromJson(json, TestRecord.class); + + assertThat(actual) + .as("Deserialized object should match expected value") + .isEqualTo(expected); + } + + @Test + void fromJsonWithClassWhenInputIsInvalid() { + var json = "{\"name\":\"John Doe\",\"age\":\"30\""; + + assertThatThrownBy(() -> jsonService.fromJson(json, TestRecord.class)) + .as("Should throw IllegalArgumentException when input is invalid") + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Unable to read object of class [ch.phoenixtechnologies.quarkus.commons.json.JsonServiceImplTest$TestRecord] from json String: {\"name\":\"John Doe\",\"age\":\"30\""); + } + + @Test + void fromJsonWithTypeReference() { + var json = "[{\"name\":\"John Doe\",\"age\":30},{\"name\":\"Jane Doe\",\"age\":25}]"; + var expected = List.of(new TestRecord("John Doe", 30), new TestRecord("Jane Doe", 25)); + + var actual = jsonService.fromJson(json, TYPE_REFERENCE); + + Assertions.assertThat(actual) + .as("Deserialized object should match expected value") + .isEqualTo(expected); + } + + @Test + void fromJsonWithTypeReferenceWhenInputIsInvalid() { + var json = "{\"name\":\"John Doe\",\"age\":30},{\"name\":\"Jane Doe\",\"age\":\"25\"}"; + + assertThatThrownBy(() -> jsonService.fromJson(json, TYPE_REFERENCE)) + .as("Should throw IllegalArgumentException when input is invalid") + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Unable to read object of type [java.util.List] from json String: {\"name\":\"John Doe\",\"age\":30},{\"name\":\"Jane Doe\",\"age\":\"25\"}"); + } +} \ No newline at end of file -- 2.47.2