From 4f375d7e74bb614f83f86670171f67c639c1c5e4 Mon Sep 17 00:00:00 2001 From: Michael7371 <40476797+Michael7371@users.noreply.github.com> Date: Thu, 16 Jan 2025 10:27:42 -0700 Subject: [PATCH 1/5] update to fix PSM schema "recordGeneratedBy" field --- .../src/main/resources/schemas/schema-psm.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/jpo-ode-core/src/main/resources/schemas/schema-psm.json b/jpo-ode-core/src/main/resources/schemas/schema-psm.json index 08f3cf469..3cfe8ce95 100644 --- a/jpo-ode-core/src/main/resources/schemas/schema-psm.json +++ b/jpo-ode-core/src/main/resources/schemas/schema-psm.json @@ -101,7 +101,19 @@ "type": "string" }, "recordGeneratedBy": { - "type": "null" + "type": [ + "string", + "null" + ], + "enum": [ + "TMC", + "OBU", + "RSU", + "TMC_VIA_SAT", + "TMC_VIA_SNMP", + "UNKNOWN", + null + ] }, "sanitized": { "type": "boolean" From 736fe619fc290242d428308bc1b1d340b28701b0 Mon Sep 17 00:00:00 2001 From: Michael7371 <40476797+Michael7371@users.noreply.github.com> Date: Thu, 16 Jan 2025 10:49:47 -0700 Subject: [PATCH 2/5] added a unit test that failed on old schema --- .../dot/its/jpo/ode/model/OdePsmDataTest.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdePsmDataTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdePsmDataTest.java index 80e2231db..6a2d65af3 100644 --- a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdePsmDataTest.java +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdePsmDataTest.java @@ -17,7 +17,7 @@ public class OdePsmDataTest { private static final String ASN1_STRING = "011d0000201a0000021bd86891de75f84da101c13f042e2214141fff00022c2000270000000163b2cc7986010000"; final String json = String.format("{\"metadata\":{\"logFileName\":\"\",\"maxDurationTime\":0,\"odePacketID\":\"\",\"odeReceivedAt\":\"2023-09-21T15:30:14.926500Z\",\"odeTimStartDateTime\":\"\",\"originIp\":\"192.168.16.1\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdePsmPayload\",\"psmSource\":\"RSU\",\"receivedMessageDetails\":{\"rxSource\":\"NA\"},\"recordGeneratedAt\":\"\",\"recordType\":\"psmTx\",\"sanitized\":false,\"schemaVersion\":%s,\"securityResultCode\":\"success\",\"serialId\":{\"bundleId\":0,\"bundleSize\":1,\"recordId\":0,\"serialNumber\":0,\"streamId\":\"06cc1c17-e331-4806-a8ee-456b98c6517b\"},\"asn1\":\"%s\"},\"payload\":{\"data\":{\"accuracy\":{\"orientation\":44.9951935489,\"semiMajor\":1.0,\"semiMinor\":1.0},\"basicType\":\"aPEDESTRIAN\",\"heading\":8898,\"id\":\"24779D7E\",\"msgCnt\":26,\"position\":{\"latitude\":40.2397377,\"longitude\":-74.2761437},\"secMark\":3564,\"speed\":0},\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.J2735PSM\"}}", SCHEMA_VERSION, ASN1_STRING); - + @Test public void shouldDeserializeJson() { final var deserialized = (OdePsmData)JsonUtils.fromJson(json, OdePsmData.class); @@ -46,4 +46,19 @@ public void shouldValidateJson() throws Exception { Set validationMessages = schema.validate(node); assertEquals(String.format("Json validation errors: %s", validationMessages), 0, validationMessages.size()); } + + @Test + public void shouldValidateJson_NonNullRecordGeneratedAt() throws Exception { + final var deserialized = (OdePsmData)JsonUtils.fromJson(json, OdePsmData.class); + deserialized.getMetadata().setRecordGeneratedBy(OdeMsgMetadata.GeneratedBy.UNKNOWN); + final String serialized = deserialized.toJson(false); + + // Load json schema from resource + JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4); + final JsonSchema schema = factory.getSchema(getClass().getClassLoader().getResource("schemas/schema-psm.json").toURI()); + final JsonNode node = (JsonNode)JsonUtils.fromJson(serialized, JsonNode.class); + Set validationMessages = schema.validate(node); + assertEquals(String.format("Json validation errors: %s", validationMessages), 0, validationMessages.size()); + } + } From 08a2e58c66c9d2c3672f2e19a72b6d2f1ae0e68f Mon Sep 17 00:00:00 2001 From: Michael7371 <40476797+Michael7371@users.noreply.github.com> Date: Thu, 16 Jan 2025 11:03:07 -0700 Subject: [PATCH 3/5] address checkstyle violations --- .../dot/its/jpo/ode/model/OdePsmDataTest.java | 95 +++++++++---------- .../src/test/resources/json/sample-psm.json | 49 ++++++++++ 2 files changed, 94 insertions(+), 50 deletions(-) create mode 100644 jpo-ode-core/src/test/resources/json/sample-psm.json diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdePsmDataTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdePsmDataTest.java index 6a2d65af3..d7662c7d9 100644 --- a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdePsmDataTest.java +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdePsmDataTest.java @@ -1,64 +1,59 @@ package us.dot.its.jpo.ode.model; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import com.fasterxml.jackson.databind.JsonNode; import com.networknt.schema.JsonSchema; import com.networknt.schema.JsonSchemaFactory; import com.networknt.schema.SpecVersion; import com.networknt.schema.ValidationMessage; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Set; - import org.junit.Test; -import static org.junit.Assert.*; - import us.dot.its.jpo.ode.util.JsonUtils; +/** + * Unit test class for OdePsmData. + */ public class OdePsmDataTest { - private static final String SCHEMA_VERSION = "8"; - private static final String ASN1_STRING = "011d0000201a0000021bd86891de75f84da101c13f042e2214141fff00022c2000270000000163b2cc7986010000"; - - final String json = String.format("{\"metadata\":{\"logFileName\":\"\",\"maxDurationTime\":0,\"odePacketID\":\"\",\"odeReceivedAt\":\"2023-09-21T15:30:14.926500Z\",\"odeTimStartDateTime\":\"\",\"originIp\":\"192.168.16.1\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdePsmPayload\",\"psmSource\":\"RSU\",\"receivedMessageDetails\":{\"rxSource\":\"NA\"},\"recordGeneratedAt\":\"\",\"recordType\":\"psmTx\",\"sanitized\":false,\"schemaVersion\":%s,\"securityResultCode\":\"success\",\"serialId\":{\"bundleId\":0,\"bundleSize\":1,\"recordId\":0,\"serialNumber\":0,\"streamId\":\"06cc1c17-e331-4806-a8ee-456b98c6517b\"},\"asn1\":\"%s\"},\"payload\":{\"data\":{\"accuracy\":{\"orientation\":44.9951935489,\"semiMajor\":1.0,\"semiMinor\":1.0},\"basicType\":\"aPEDESTRIAN\",\"heading\":8898,\"id\":\"24779D7E\",\"msgCnt\":26,\"position\":{\"latitude\":40.2397377,\"longitude\":-74.2761437},\"secMark\":3564,\"speed\":0},\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.J2735PSM\"}}", SCHEMA_VERSION, ASN1_STRING); - - @Test - public void shouldDeserializeJson() { - final var deserialized = (OdePsmData)JsonUtils.fromJson(json, OdePsmData.class); - assertNotNull(deserialized); - assertTrue(deserialized.getMetadata() instanceof OdePsmMetadata); - assertTrue(deserialized.getPayload() instanceof OdePsmPayload); - - } - - @Test - public void serializationShouldNotAddClassProperty() { - final var deserialized = (OdePsmData)JsonUtils.fromJson(json, OdePsmData.class); - final String serialized = deserialized.toJson(false); - assertFalse(serialized.contains("@class")); - } - - @Test - public void shouldValidateJson() throws Exception { - final var deserialized = (OdePsmData)JsonUtils.fromJson(json, OdePsmData.class); - final String serialized = deserialized.toJson(false); - - // Load json schema from resource - JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4); - final JsonSchema schema = factory.getSchema(getClass().getClassLoader().getResource("schemas/schema-psm.json").toURI()); - final JsonNode node = (JsonNode)JsonUtils.fromJson(serialized, JsonNode.class); - Set validationMessages = schema.validate(node); - assertEquals(String.format("Json validation errors: %s", validationMessages), 0, validationMessages.size()); - } - - @Test - public void shouldValidateJson_NonNullRecordGeneratedAt() throws Exception { - final var deserialized = (OdePsmData)JsonUtils.fromJson(json, OdePsmData.class); - deserialized.getMetadata().setRecordGeneratedBy(OdeMsgMetadata.GeneratedBy.UNKNOWN); - final String serialized = deserialized.toJson(false); - - // Load json schema from resource - JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4); - final JsonSchema schema = factory.getSchema(getClass().getClassLoader().getResource("schemas/schema-psm.json").toURI()); - final JsonNode node = (JsonNode)JsonUtils.fromJson(serialized, JsonNode.class); - Set validationMessages = schema.validate(node); - assertEquals(String.format("Json validation errors: %s", validationMessages), 0, validationMessages.size()); - } + private String loadTestJson() throws IOException { + return new String(getClass().getClassLoader() + .getResourceAsStream("json/sample-psm.json") + .readAllBytes(), StandardCharsets.UTF_8); + } + + @Test + public void shouldDeserializeJson() throws IOException { + final var deserialized = (OdePsmData) JsonUtils.fromJson(loadTestJson(), OdePsmData.class); + assertNotNull(deserialized); + assertTrue(deserialized.getMetadata() instanceof OdePsmMetadata); + assertTrue(deserialized.getPayload() instanceof OdePsmPayload); + + } + + @Test + public void serializationShouldNotAddClassProperty() throws IOException { + final var deserialized = (OdePsmData) JsonUtils.fromJson(loadTestJson(), OdePsmData.class); + final String serialized = deserialized.toJson(false); + assertFalse(serialized.contains("@class")); + } + + @Test + public void shouldValidateJson() throws Exception { + final var deserialized = (OdePsmData) JsonUtils.fromJson(loadTestJson(), OdePsmData.class); + final String serialized = deserialized.toJson(false); + + // Load json schema from resource + JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4); + final JsonSchema schema = + factory.getSchema(getClass().getClassLoader().getResource("schemas/schema-psm.json").toURI()); + final JsonNode node = (JsonNode) JsonUtils.fromJson(serialized, JsonNode.class); + Set validationMessages = schema.validate(node); + assertEquals(String.format("Json validation errors: %s", validationMessages), 0, validationMessages.size()); + } } diff --git a/jpo-ode-core/src/test/resources/json/sample-psm.json b/jpo-ode-core/src/test/resources/json/sample-psm.json new file mode 100644 index 000000000..c49303d90 --- /dev/null +++ b/jpo-ode-core/src/test/resources/json/sample-psm.json @@ -0,0 +1,49 @@ +{ + "metadata": { + "logFileName": "", + "maxDurationTime": 0, + "odePacketID": "", + "odeReceivedAt": "2023-09-21T15:30:14.926500Z", + "odeTimStartDateTime": "", + "originIp": "192.168.16.1", + "payloadType": "us.dot.its.jpo.ode.model.OdePsmPayload", + "psmSource": "RSU", + "receivedMessageDetails": { + "rxSource": "NA" + }, + "recordGeneratedAt": "", + "recordGeneratedBy": "UNKNOWN", + "recordType": "psmTx", + "sanitized": false, + "schemaVersion": 8, + "securityResultCode": "success", + "serialId": { + "bundleId": 0, + "bundleSize": 1, + "recordId": 0, + "serialNumber": 0, + "streamId": "06cc1c17-e331-4806-a8ee-456b98c6517b" + }, + "asn1": "011d0000201a0000021bd86891de75f84da101c13f042e2214141fff00022c2000270000000163b2cc7986010000" + }, + "payload": { + "data": { + "accuracy": { + "orientation": 44.9951935489, + "semiMajor": 1.0, + "semiMinor": 1.0 + }, + "basicType": "aPEDESTRIAN", + "heading": 8898, + "id": "24779D7E", + "msgCnt": 26, + "position": { + "latitude": 40.2397377, + "longitude": -74.2761437 + }, + "secMark": 3564, + "speed": 0 + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735PSM" + } +} \ No newline at end of file From 97b1c2fffadfdc984b8c6b1e43c77c3065338d87 Mon Sep 17 00:00:00 2001 From: Michael7371 <40476797+Michael7371@users.noreply.github.com> Date: Thu, 16 Jan 2025 11:09:43 -0700 Subject: [PATCH 4/5] adding PSM schema fix to the release notes --- docs/Release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Release_notes.md b/docs/Release_notes.md index 5b41b87ef..73893a70b 100644 --- a/docs/Release_notes.md +++ b/docs/Release_notes.md @@ -63,6 +63,7 @@ Enhancements in this release: - [CDOT PR 154](https://github.com/CDOT-CV/jpo-ode/pull/154): Fix: Use odeKafkaProperties env vars to drive producer retries - [USDOT PR 559](https://github.com/usdot-jpo-ode/jpo-ode/pull/559): Update GitHub Actions Third-Party Action Versions - [USDOT PR 561](https://github.com/usdot-jpo-ode/jpo-ode/pull/561): Bump ch.qos.logback:logback-core from 1.4.14 to 1.5.13 in /jpo-ode-plugins +- [CDOT PR 155](https://github.com/CDOT-CV/jpo-ode/pull/158): Fix: PSM Schema bug fix Breaking changes: - The major version was incremented due to breaking changes in the 2024 revision of J2735. From 3a95b03065e4dd2032109182f0ba181294fdb999 Mon Sep 17 00:00:00 2001 From: Michael7371 <40476797+Michael7371@users.noreply.github.com> Date: Thu, 16 Jan 2025 10:12:38 -0800 Subject: [PATCH 5/5] Update docs/Release_notes.md fixing release notes for PSM schema fix Co-authored-by: Daniel McCoy Stephenson --- docs/Release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Release_notes.md b/docs/Release_notes.md index 73893a70b..90bd4b89b 100644 --- a/docs/Release_notes.md +++ b/docs/Release_notes.md @@ -63,7 +63,7 @@ Enhancements in this release: - [CDOT PR 154](https://github.com/CDOT-CV/jpo-ode/pull/154): Fix: Use odeKafkaProperties env vars to drive producer retries - [USDOT PR 559](https://github.com/usdot-jpo-ode/jpo-ode/pull/559): Update GitHub Actions Third-Party Action Versions - [USDOT PR 561](https://github.com/usdot-jpo-ode/jpo-ode/pull/561): Bump ch.qos.logback:logback-core from 1.4.14 to 1.5.13 in /jpo-ode-plugins -- [CDOT PR 155](https://github.com/CDOT-CV/jpo-ode/pull/158): Fix: PSM Schema bug fix +- [CDOT PR 158](https://github.com/CDOT-CV/jpo-ode/pull/158): Release/PSM schema fix Breaking changes: - The major version was incremented due to breaking changes in the 2024 revision of J2735.