Skip to content

Commit 91537da

Browse files
authored
Improve cloud event to json conversion (#1445)
Relies on SDK serialization/deserialization. Adds small patch to be compliant with expected behaviour Signed-off-by: fjtirado <ftirados@ibm.com>
1 parent cafd804 commit 91537da

2 files changed

Lines changed: 57 additions & 21 deletions

File tree

impl/json-utils/src/main/java/io/serverlessworkflow/impl/jackson/JacksonCloudEventUtils.java

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@
1515
*/
1616
package io.serverlessworkflow.impl.jackson;
1717

18-
import com.fasterxml.jackson.core.JsonProcessingException;
1918
import com.fasterxml.jackson.databind.JsonNode;
2019
import com.fasterxml.jackson.databind.node.NullNode;
20+
import com.fasterxml.jackson.databind.node.ObjectNode;
21+
import com.fasterxml.jackson.databind.node.POJONode;
2122
import io.cloudevents.CloudEvent;
2223
import io.cloudevents.CloudEventData;
23-
import io.cloudevents.core.provider.EventFormatProvider;
2424
import io.cloudevents.jackson.JsonCloudEventData;
25-
import io.cloudevents.jackson.JsonFormat;
2625
import java.io.IOException;
2726
import java.io.UncheckedIOException;
2827
import java.time.OffsetDateTime;
@@ -35,14 +34,11 @@ public static JsonNode toJsonNode(CloudEvent event) {
3534
if (event == null) {
3635
return NullNode.instance;
3736
}
38-
// Delegate entirely to the official CloudEvents SDK
39-
byte[] serialized =
40-
EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE).serialize(event);
41-
try {
42-
return JsonUtils.mapper().readTree(serialized);
43-
} catch (IOException e) {
44-
throw new UncheckedIOException(e);
37+
ObjectNode node = JsonUtils.mapper().convertValue(event, ObjectNode.class);
38+
if (node.get("data") instanceof POJONode) {
39+
node.set("data", toJsonNode(event.getData()));
4540
}
41+
return node;
4642
}
4743

4844
public static OffsetDateTime toOffset(Date date) {
@@ -66,14 +62,7 @@ public static CloudEvent toCloudEvent(JsonNode node) {
6662
if (node == null || node.isNull()) {
6763
return null;
6864
}
69-
try {
70-
byte[] ceBytes = JsonUtils.mapper().writeValueAsBytes(node);
71-
return EventFormatProvider.getInstance()
72-
.resolveFormat(JsonFormat.CONTENT_TYPE)
73-
.deserialize(ceBytes);
74-
} catch (JsonProcessingException e) {
75-
throw new IllegalArgumentException("Failed to deserialize JsonNode to CloudEvent", e);
76-
}
65+
return JsonUtils.mapper().convertValue(node, CloudEvent.class);
7766
}
7867

7968
public static CloudEventData toCloudEventData(JsonNode node) {

impl/json-utils/src/test/java/io/serverlessworkflow/impl/jackson/JacksonCloudEventUtilsTest.java

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,44 @@
2525
import io.cloudevents.CloudEventData;
2626
import io.cloudevents.core.builder.CloudEventBuilder;
2727
import io.cloudevents.core.data.BytesCloudEventData;
28+
import io.cloudevents.jackson.JsonCloudEventData;
2829
import java.net.URI;
2930
import java.nio.charset.StandardCharsets;
3031
import org.junit.jupiter.api.Test;
3132

3233
public class JacksonCloudEventUtilsTest {
3334

3435
private CloudEvent createSampleEvent() {
36+
return createEventBuilder()
37+
.withData("{\"status\":\"NEEDS_REVISION\"}".getBytes(StandardCharsets.UTF_8))
38+
.build();
39+
}
40+
41+
private CloudEventBuilder createEventBuilder() {
3542
return CloudEventBuilder.v1()
3643
.withId("5dc4698e-5f98-470e-bb76-04218fe2dd0f")
3744
.withSource(URI.create("api:/newsletter"))
3845
.withType("org.acme.newsletter.review.done")
3946
.withDataContentType("application/json")
40-
.withExtension("flowinstanceid", "01KMRBFA19GZYW3XY895Z4SNCK")
41-
.withData("{\"status\":\"NEEDS_REVISION\"}".getBytes(StandardCharsets.UTF_8))
42-
.build();
47+
.withExtension("flowinstanceid", "01KMRBFA19GZYW3XY895Z4SNCK");
48+
}
49+
50+
@Test
51+
public void testCloudEventSerializationNullData() {
52+
CloudEvent event = createEventBuilder().build();
53+
54+
JsonNode node = JacksonCloudEventUtils.toJsonNode(event);
55+
56+
assertNotNull(node);
57+
assertTrue(node.has("specversion"), "Missing mandatory specversion attribute");
58+
assertEquals("1.0", node.get("specversion").asText());
59+
60+
assertFalse(node.has("specVersion"), "Jackson POJO serializer mangled the envelope!");
61+
62+
assertEquals("5dc4698e-5f98-470e-bb76-04218fe2dd0f", node.get("id").asText());
63+
assertEquals("01KMRBFA19GZYW3XY895Z4SNCK", node.get("flowinstanceid").asText());
64+
65+
assertFalse(node.has("data"));
4366
}
4467

4568
@Test
@@ -61,6 +84,30 @@ public void testCloudEventSerialization() {
6184
assertEquals("NEEDS_REVISION", node.get("data").get("status").asText());
6285
}
6386

87+
@Test
88+
public void testCloudEventSerializationJson() {
89+
CloudEvent event =
90+
createEventBuilder()
91+
.withData(
92+
JsonCloudEventData.wrap(
93+
JsonUtils.mapper().createObjectNode().put("status", "NEEDS_REVISION")))
94+
.build();
95+
96+
JsonNode node = JacksonCloudEventUtils.toJsonNode(event);
97+
98+
assertNotNull(node);
99+
assertTrue(node.has("specversion"), "Missing mandatory specversion attribute");
100+
assertEquals("1.0", node.get("specversion").asText());
101+
102+
assertFalse(node.has("specVersion"), "Jackson POJO serializer mangled the envelope!");
103+
104+
assertEquals("5dc4698e-5f98-470e-bb76-04218fe2dd0f", node.get("id").asText());
105+
assertEquals("01KMRBFA19GZYW3XY895Z4SNCK", node.get("flowinstanceid").asText());
106+
107+
assertTrue(node.has("data"));
108+
assertEquals("NEEDS_REVISION", node.get("data").get("status").asText());
109+
}
110+
64111
@Test
65112
public void testCloudEventDeserialization() {
66113
CloudEvent originalEvent = createSampleEvent();

0 commit comments

Comments
 (0)