Skip to content

Commit 1d42acc

Browse files
authored
Fix not to render optional fields when unset (#55)
* Fix not to render optional fields when unset * Adding CDEvent validation with test data optional fields unset * fixing linter issues and override hashCode * test validation with JsonNode
1 parent 0e99ff6 commit 1d42acc

File tree

8 files changed

+295
-5
lines changed

8 files changed

+295
-5
lines changed

src/main/java/dev/cdevents/CDEvents.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ public static CloudEvent cdEventAsCloudEvent(CDEvent cdEvent) {
7474
* @return valid cdEvent
7575
*/
7676
public static boolean validateCDEvent(CDEvent cdEvent) {
77-
String cdEventJson = cdEventAsJson(cdEvent);
78-
7977
JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012);
8078
JsonSchema jsonSchema = factory.getSchema(cdEvent.eventSchema());
8179

src/main/java/dev/cdevents/config/CustomObjectMapper.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.cdevents.config;
22

3+
import com.fasterxml.jackson.annotation.JsonInclude;
34
import com.fasterxml.jackson.databind.DeserializationFeature;
45
import com.fasterxml.jackson.databind.ObjectMapper;
56
import com.fasterxml.jackson.databind.SerializationFeature;
@@ -15,6 +16,7 @@ public ObjectMapper customConfiguration() {
1516
.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
1617
.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING)
1718
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
19+
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
1820
.registerModule(new JavaTimeModule());
1921
}
2022
}

src/test/java/dev/cdevents/CDEventsTest.java

Lines changed: 195 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
11
package dev.cdevents;
22

33
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.JsonNode;
5+
import com.fasterxml.jackson.databind.ObjectMapper;
46
import com.github.packageurl.MalformedPackageURLException;
57
import com.github.packageurl.PackageURL;
8+
import dev.cdevents.config.CustomObjectMapper;
69
import dev.cdevents.constants.CDEventConstants;
710
import dev.cdevents.events.*;
811
import dev.cdevents.exception.CDEventsException;
912
import io.cloudevents.CloudEvent;
1013
import org.junit.jupiter.api.Test;
1114

15+
import java.io.IOException;
16+
import java.io.InputStream;
1217
import java.net.URI;
1318
import java.nio.charset.StandardCharsets;
1419

1520
import static org.assertj.core.api.Assertions.assertThat;
16-
import static org.junit.jupiter.api.Assertions.assertThrows;
21+
import static org.junit.jupiter.api.Assertions.*;
1722

1823
public class CDEventsTest {
1924

20-
@Test
21-
void createPipelineRunFinishedEventAsCloudEvent() {
25+
private static ObjectMapper objectMapper = new CustomObjectMapper().customConfiguration();
2226

27+
@Test
28+
void createPipelineRunFinishedEventAsCloudEvent() throws IOException {
2329
PipelineRunFinishedCDEvent cdEvent = new PipelineRunFinishedCDEvent();
2430
cdEvent.setSource(URI.create("http://dev.cdevents"));
2531

@@ -42,6 +48,42 @@ void createPipelineRunFinishedEventAsCloudEvent() {
4248

4349
}
4450

51+
@Test
52+
void createPipelineRunFinishedEventOptionalFieldsUnset() throws IOException {
53+
InputStream inputStream = getClass().getResourceAsStream("/pipelinerun_finished_optional.json");
54+
55+
JsonNode expectedJsonNode = objectMapper.readTree(inputStream);
56+
JsonNode expectedContextNode = expectedJsonNode.get("context");
57+
JsonNode expectedSubjectNode = expectedJsonNode.get("subject");
58+
59+
PipelineRunFinishedCDEvent cdEvent = new PipelineRunFinishedCDEvent();
60+
cdEvent.setSource(URI.create(expectedContextNode.get("source").asText()));
61+
cdEvent.setSubjectId(expectedSubjectNode.get("id").asText());
62+
63+
String cdEventJson = CDEvents.cdEventAsJson(cdEvent);
64+
JsonNode cdEventJsonNode = objectMapper.readTree(cdEventJson);
65+
JsonNode cdEventContextNode = cdEventJsonNode.get("context");
66+
JsonNode cdEventSubjectNode = cdEventJsonNode.get("subject");
67+
68+
//validates CDEvent against schema
69+
assertTrue(CDEvents.validateCDEvent(cdEvent));
70+
71+
//assert context and subject mandatory fields
72+
assertThat(cdEventContextNode.get("type").asText()).isEqualTo(expectedContextNode.get("type").asText());
73+
assertThat(cdEventContextNode.get("source").asText()).isEqualTo(expectedContextNode.get("source").asText());
74+
assertEquals(expectedSubjectNode, cdEventSubjectNode);
75+
assertThat(cdEventSubjectNode.get("id").asText()).isEqualTo(expectedSubjectNode.get("id").asText());
76+
assertThat(cdEventSubjectNode.get("type").asText()).isEqualTo(expectedSubjectNode.get("type").asText());
77+
78+
//assert Optional field Subject Source, Content pipelineName, url, outcome, errors are set to null
79+
assertThat(cdEventSubjectNode.get("source")).isEqualTo(null);
80+
assertThat(expectedSubjectNode.get("content").get("pipelineName")).isEqualTo(null);
81+
assertThat(expectedSubjectNode.get("content").get("url")).isEqualTo(null);
82+
assertThat(expectedSubjectNode.get("content").get("outcome")).isEqualTo(null);
83+
assertThat(expectedSubjectNode.get("content").get("errors")).isEqualTo(null);
84+
85+
}
86+
4587
@Test
4688
void testInvalidPipelineRunFinishedEventWithNoSubject() {
4789
PipelineRunFinishedCDEvent cdEvent = new PipelineRunFinishedCDEvent();
@@ -90,6 +132,41 @@ void testInvalidPipelineRunQueuedEventWithNoSubject() {
90132
assertThat(exception.getMessage()).isEqualTo(expectedError);
91133
}
92134

135+
@Test
136+
void createPipelineRunQueuedEventWithOptionalFieldsUnset() throws IOException {
137+
InputStream inputStream = getClass().getResourceAsStream("/pipelinerun_queued_optional.json");
138+
139+
JsonNode expectedJsonNode = objectMapper.readTree(inputStream);
140+
JsonNode expectedContextNode = expectedJsonNode.get("context");
141+
JsonNode expectedSubjectNode = expectedJsonNode.get("subject");
142+
143+
PipelineRunQueuedCDEvent cdEvent = new PipelineRunQueuedCDEvent();
144+
cdEvent.setSource(URI.create(expectedContextNode.get("source").asText()));
145+
cdEvent.setSubjectId(expectedSubjectNode.get("id").asText());
146+
147+
String cdEventJson = CDEvents.cdEventAsJson(cdEvent);
148+
JsonNode cdEventJsonNode = objectMapper.readTree(cdEventJson);
149+
JsonNode cdEventContextNode = cdEventJsonNode.get("context");
150+
JsonNode cdEventSubjectNode = cdEventJsonNode.get("subject");
151+
152+
//validates CDEvent against schema
153+
assertTrue(CDEvents.validateCDEvent(cdEvent));
154+
155+
//assert context and subject mandatory fields
156+
assertThat(cdEventContextNode.get("type").asText()).isEqualTo(expectedContextNode.get("type").asText());
157+
assertThat(cdEventContextNode.get("source").asText()).isEqualTo(expectedContextNode.get("source").asText());
158+
assertEquals(expectedSubjectNode, cdEventSubjectNode);
159+
assertThat(cdEventSubjectNode.get("id").asText()).isEqualTo(expectedSubjectNode.get("id").asText());
160+
assertThat(cdEventSubjectNode.get("type").asText()).isEqualTo(expectedSubjectNode.get("type").asText());
161+
162+
//assert Optional field Subject Source, pipelineName, url is set to null
163+
assertThat(cdEventSubjectNode.get("source")).isEqualTo(null);
164+
assertThat(expectedSubjectNode.get("content").get("pipelineName")).isEqualTo(null);
165+
assertThat(expectedSubjectNode.get("content").get("url")).isEqualTo(null);
166+
167+
168+
}
169+
93170
@Test
94171
void testPipelineRunQueuedEventWithCustomData() throws JsonProcessingException {
95172
PipelineRunQueuedCDEvent cdEvent = new PipelineRunQueuedCDEvent();
@@ -151,6 +228,44 @@ void testInvalidPipelineRunStartedEventWithNoSubject() {
151228
assertThat(exception.getMessage()).isEqualTo(expectedError);
152229
}
153230

231+
@Test
232+
void createPipelineRunStartedJsonEventWithOptionalFieldsUnset() throws IOException {
233+
234+
InputStream inputStream = getClass().getResourceAsStream("/pipelinerun_started_optional.json");
235+
236+
JsonNode expectedJsonNode = objectMapper.readTree(inputStream);
237+
JsonNode expectedContextNode = expectedJsonNode.get("context");
238+
JsonNode expectedSubjectNode = expectedJsonNode.get("subject");
239+
240+
PipelineRunStartedCDEvent cdEvent = new PipelineRunStartedCDEvent();
241+
cdEvent.setSource(URI.create(expectedContextNode.get("source").asText()));
242+
243+
cdEvent.setSubjectId(expectedSubjectNode.get("id").asText());
244+
cdEvent.setSubjectPipelineName(expectedSubjectNode.get("content").get("pipelineName").asText());
245+
cdEvent.setSubjectUrl(URI.create(expectedSubjectNode.get("content").get("url").asText()));
246+
247+
String cdEventJson = CDEvents.cdEventAsJson(cdEvent);
248+
JsonNode cdEventJsonNode = objectMapper.readTree(cdEventJson);
249+
JsonNode cdEventContextNode = cdEventJsonNode.get("context");
250+
JsonNode cdEventSubjectNode = cdEventJsonNode.get("subject");
251+
252+
//validates CDEvent against schema
253+
assertTrue(CDEvents.validateCDEvent(cdEvent));
254+
255+
//assert context and subject mandatory fields
256+
assertThat(cdEventContextNode.get("type").asText()).isEqualTo(expectedContextNode.get("type").asText());
257+
assertThat(cdEventContextNode.get("source").asText()).isEqualTo(expectedContextNode.get("source").asText());
258+
assertEquals(expectedSubjectNode, cdEventSubjectNode);
259+
assertThat(cdEventSubjectNode.get("id").asText()).isEqualTo(expectedSubjectNode.get("id").asText());
260+
assertThat(cdEventSubjectNode.get("type").asText()).isEqualTo(expectedSubjectNode.get("type").asText());
261+
assertThat(cdEventSubjectNode.get("content").get("pipelineName").asText()).isEqualTo(expectedSubjectNode.get("content").get("pipelineName").asText());
262+
assertThat(cdEventSubjectNode.get("content").get("url").asText()).isEqualTo(expectedSubjectNode.get("content").get("url").asText());
263+
264+
//assert Optional field Subject Source is set to null
265+
assertThat(cdEventSubjectNode.get("source")).isEqualTo(null);
266+
267+
}
268+
154269

155270
@Test
156271
void createTaskRunStartedEventAsCloudEvent() {
@@ -189,6 +304,44 @@ void testInvalidTaskRunStartedEventWithNoSubject() {
189304
assertThat(exception.getMessage()).isEqualTo(expectedError);
190305
}
191306

307+
@Test
308+
void createTaskRunStartedEventJsonWithOptionalFieldsUnset() throws IOException {
309+
InputStream inputStream = getClass().getResourceAsStream("/taskrun_started_optional.json");
310+
311+
JsonNode expectedJsonNode = objectMapper.readTree(inputStream);
312+
JsonNode expectedContextNode = expectedJsonNode.get("context");
313+
JsonNode expectedSubjectNode = expectedJsonNode.get("subject");
314+
315+
TaskRunStartedCDEvent cdEvent = new TaskRunStartedCDEvent();
316+
cdEvent.setSource(URI.create(expectedContextNode.get("source").asText()));
317+
318+
cdEvent.setSubjectId(expectedSubjectNode.get("id").asText());
319+
cdEvent.setSubjectPipelineRunId(expectedSubjectNode.get("content").get("pipelineRun").get("id").asText());
320+
321+
String cdEventJson = CDEvents.cdEventAsJson(cdEvent);
322+
JsonNode cdEventJsonNode = objectMapper.readTree(cdEventJson);
323+
JsonNode cdEventContextNode = cdEventJsonNode.get("context");
324+
JsonNode cdEventSubjectNode = cdEventJsonNode.get("subject");
325+
326+
//validates CDEvent against schema
327+
assertTrue(CDEvents.validateCDEvent(cdEvent));
328+
329+
//assert context and subject mandatory fields
330+
assertThat(cdEventContextNode.get("type").asText()).isEqualTo(expectedContextNode.get("type").asText());
331+
assertThat(cdEventContextNode.get("source").asText()).isEqualTo(expectedContextNode.get("source").asText());
332+
assertEquals(expectedSubjectNode, cdEventSubjectNode);
333+
assertThat(cdEventSubjectNode.get("id").asText()).isEqualTo(expectedSubjectNode.get("id").asText());
334+
assertThat(cdEventSubjectNode.get("type").asText()).isEqualTo(expectedSubjectNode.get("type").asText());
335+
assertThat(cdEventSubjectNode.get("content").get("pipelineRun").get("id").asText()).isEqualTo(expectedSubjectNode.get("content").get("pipelineRun").get("id").asText());
336+
337+
//assert Optional fields Subject Source, Content taskName, URL and pipelineRun Source are set to null
338+
assertThat(cdEventSubjectNode.get("source")).isEqualTo(null);
339+
assertThat(cdEventSubjectNode.get("content").get("taskName")).isEqualTo(null);
340+
assertThat(cdEventSubjectNode.get("content").get("url")).isEqualTo(null);
341+
assertThat(cdEventSubjectNode.get("content").get("pipelineRun").get("source")).isEqualTo(null);
342+
343+
}
344+
192345
@Test
193346
void createTaskRunFinishedEventAsCloudEvent() {
194347

@@ -215,6 +368,45 @@ void createTaskRunFinishedEventAsCloudEvent() {
215368
assertThat(ceDataJson).isEqualTo(cdEventJson);
216369
}
217370

371+
@Test
372+
void createTaskRunFinishedEventJsonWithOptionalFieldsUnset() throws IOException {
373+
374+
InputStream inputStream = getClass().getResourceAsStream("/taskrun_finished_optional.json");
375+
376+
JsonNode expectedJsonNode = objectMapper.readTree(inputStream);
377+
JsonNode expectedContextNode = expectedJsonNode.get("context");
378+
JsonNode expectedSubjectNode = expectedJsonNode.get("subject");
379+
380+
TaskRunFinishedCDEvent cdEvent = new TaskRunFinishedCDEvent();
381+
cdEvent.setSource(URI.create(expectedContextNode.get("source").asText()));
382+
cdEvent.setSubjectId(expectedSubjectNode.get("id").asText());
383+
cdEvent.setSubjectPipelineRunId(expectedSubjectNode.get("content").get("pipelineRun").get("id").asText());
384+
385+
String cdEventJson = CDEvents.cdEventAsJson(cdEvent);
386+
JsonNode cdEventJsonNode = objectMapper.readTree(cdEventJson);
387+
JsonNode cdEventContextNode = cdEventJsonNode.get("context");
388+
JsonNode cdEventSubjectNode = cdEventJsonNode.get("subject");
389+
390+
//validates CDEvent against schema
391+
assertTrue(CDEvents.validateCDEvent(cdEvent));
392+
393+
//assert context and subject mandatory fields
394+
assertThat(cdEventContextNode.get("type").asText()).isEqualTo(expectedContextNode.get("type").asText());
395+
assertThat(cdEventContextNode.get("source").asText()).isEqualTo(expectedContextNode.get("source").asText());
396+
assertEquals(expectedSubjectNode, cdEventSubjectNode);
397+
assertThat(cdEventSubjectNode.get("id").asText()).isEqualTo(expectedSubjectNode.get("id").asText());
398+
assertThat(cdEventSubjectNode.get("type").asText()).isEqualTo(expectedSubjectNode.get("type").asText());
399+
assertThat(cdEventSubjectNode.get("content").get("pipelineRun").get("id").asText()).isEqualTo(expectedSubjectNode.get("content").get("pipelineRun").get("id").asText());
400+
401+
//assert Optional fields Subject Source, Content taskName, URL, outcome, errors and pipelineRun Source are set to null
402+
assertThat(cdEventSubjectNode.get("source")).isEqualTo(null);
403+
assertThat(cdEventSubjectNode.get("content").get("taskName")).isEqualTo(null);
404+
assertThat(cdEventSubjectNode.get("content").get("url")).isEqualTo(null);
405+
assertThat(cdEventSubjectNode.get("content").get("outcome")).isEqualTo(null);
406+
assertThat(cdEventSubjectNode.get("content").get("errors")).isEqualTo(null);
407+
assertThat(cdEventSubjectNode.get("content").get("pipelineRun").get("source")).isEqualTo(null);
408+
}
409+
218410
@Test
219411
void testInvalidTaskRunFinishedEventWithNoSubject() {
220412
TaskRunFinishedCDEvent cdEvent = new TaskRunFinishedCDEvent();
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"context": {
3+
"id": "123456789",
4+
"type": "dev.cdevents.pipelinerun.finished.0.1.0",
5+
"source": "http://dev.cdevents",
6+
"version": "0.1.2",
7+
"timestamp": "2023-05-24T11:17:06Z"
8+
},
9+
"customData": {
10+
},
11+
"customDataContentType": "application/json",
12+
"subject": {
13+
"id": "/dev/pipeline/run/subject",
14+
"type": "PIPELINERUN",
15+
"content": {
16+
}
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"context": {
3+
"id": "dc0bf5f5-f2e4-44c3-b9a6-1f0cf51b050b",
4+
"type": "dev.cdevents.pipelinerun.queued.0.1.0",
5+
"source": "http://dev.cdevents",
6+
"version": "0.1.2",
7+
"timestamp": "2023-05-24T18:34:41Z"
8+
},
9+
"customData": {
10+
},
11+
"customDataContentType": "application/json",
12+
"subject": {
13+
"id": "/dev/pipeline/run/subject",
14+
"type": "PIPELINERUN",
15+
"content": {
16+
}
17+
}
18+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"context": {
3+
"id": "cbde772c-17ad-490d-aea0-41fb060d1483",
4+
"type": "dev.cdevents.pipelinerun.started.0.1.0",
5+
"source": "http://dev.cdevents",
6+
"version": "0.1.2",
7+
"timestamp": "2023-05-24T18:48:12Z"
8+
},
9+
"customData": {
10+
},
11+
"customDataContentType": "application/json",
12+
"subject": {
13+
"id": "/dev/pipeline/run/subject",
14+
"type": "PIPELINERUN",
15+
"content": {
16+
"pipelineName": "test-pipeline-started",
17+
"url": "http://dev/pipeline/url"
18+
}
19+
}
20+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"context": {
3+
"id": "49e16403-c5b5-4e2a-9540-160787459a21",
4+
"type": "dev.cdevents.taskrun.finished.0.1.0",
5+
"source": "http://dev.cdevents",
6+
"version": "0.1.2",
7+
"timestamp": "2023-05-24T19:20:57Z"
8+
},
9+
"customData": {
10+
},
11+
"customDataContentType": "application/json",
12+
"subject": {
13+
"id": "/dev/task/run/subject",
14+
"type": "TASKRUN",
15+
"content": {
16+
"pipelineRun": {
17+
"id": "/dev/pipeline/run/subject"
18+
}
19+
}
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"context": {
3+
"id": "f75eb164-947c-4827-9036-9ec7fda38873",
4+
"type": "dev.cdevents.taskrun.started.0.1.0",
5+
"source": "http://dev.cdevents",
6+
"version": "0.1.2",
7+
"timestamp": "2023-05-24T19:16:11Z"
8+
},
9+
"customData": {
10+
},
11+
"customDataContentType": "application/json",
12+
"subject": {
13+
"id": "/dev/task/run/subject",
14+
"type": "TASKRUN",
15+
"content": {
16+
"pipelineRun": {
17+
"id": "/dev/pipeline/run/subject"
18+
}
19+
}
20+
}
21+
}

0 commit comments

Comments
 (0)