Skip to content

Commit

Permalink
Merge pull request #158 from CDOT-CV/release/psm-schema-fix
Browse files Browse the repository at this point in the history
Release/PSM schema fix
  • Loading branch information
drewjj authored Jan 16, 2025
2 parents e584738 + 3a95b03 commit 501a1f5
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 37 deletions.
1 change: 1 addition & 0 deletions docs/Release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 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.
Expand Down
14 changes: 13 additions & 1 deletion jpo-ode-core/src/main/resources/schemas/schema-psm.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,49 +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<ValidationMessage> 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<ValidationMessage> validationMessages = schema.validate(node);
assertEquals(String.format("Json validation errors: %s", validationMessages), 0, validationMessages.size());
}

}
49 changes: 49 additions & 0 deletions jpo-ode-core/src/test/resources/json/sample-psm.json
Original file line number Diff line number Diff line change
@@ -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"
}
}

0 comments on commit 501a1f5

Please sign in to comment.