Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/artifact-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ on:
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout code (with submodules)
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,23 @@ In order to utilize Confluent Cloud:

#### Note

### Port Mapped Receiver Configuration
Many production deployments may not send intersection data directly from an RSU unit. This often happens if another device is responsible for generating MAP / SPaT messages or if a proxy or load balancer is used between an RSU unit and the ODE. To handle these edge cases the ODE has a configurable port-mapped receiver which can be used for receiving data on a variety of ports. The intent of this feature is to allow the ODE to continue to identify different source RSU units based upon the port the data is forwarded on.

To use port-mapped ingest, add an entry similar to the below to the application.yaml file. The entry below creates a BSM receiver which listens on port 1234. Any BSM data received on port 1234 will be marked as having been received from the IP 1.2.3.4.

```
port-mapped-ingest:
sources:
- intersectipon-name: "Name"
intersection-id: 1234
origin-ip: 1.2.3.4
port: 1234
type: BSM
```

Please note, ports added here are not automatically opened in the host docker container. Any port added here should separately be added to the running docker container.

This has only been tested with Confluent Cloud but technically all SASL authenticated Kafka brokers can be reached using this method.

[Back to top](#table-of-contents)
Expand All @@ -464,6 +481,8 @@ The configuration that defines this is in the jpo-utils submodule [here](jpo-uti

For further documentation on configuring the MongoDB Kafka Connect image refer [to this readme](jpo-utils/README.md).



## Note

Kafka connect is being used for MongoDB in this implementation but it can interact with many types of databases, here is further documentation for [kafka connect](https://docs.confluent.io/platform/current/connect/index.html)
Expand Down
3 changes: 3 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ services:
ODE_ROCKSDB_BLOCK_SIZE: ${ODE_ROCKSDB_BLOCK_SIZE}
ODE_ROCKSDB_N_MEMTABLES: ${ODE_ROCKSDB_N_MEMTABLES}
ODE_ROCKSDB_MEMTABLE_SIZE: ${ODE_ROCKSDB_MEMTABLE_SIZE}
ODE_KAFKA_LISTENER_CONCURRENCY: ${ODE_KAFKA_LISTENER_CONCURRENCY}
depends_on:
kafka:
condition: service_healthy
Expand Down Expand Up @@ -104,6 +105,7 @@ services:
ACM_LOG_TO_CONSOLE: ${ADM_LOG_TO_CONSOLE}
ACM_LOG_TO_FILE: ${ADM_LOG_TO_FILE}
ACM_LOG_LEVEL: ${ADM_LOG_LEVEL}
ACM_NUMBER_OF_PROCESSES: ${ADM_NUMBER_OF_PROCESSES:-1}
depends_on:
kafka:
condition: service_healthy
Expand Down Expand Up @@ -137,6 +139,7 @@ services:
ACM_LOG_TO_CONSOLE: ${AEM_LOG_TO_CONSOLE}
ACM_LOG_TO_FILE: ${AEM_LOG_TO_FILE}
ACM_LOG_LEVEL: ${AEM_LOG_LEVEL}
ACM_NUMBER_OF_PROCESSES: ${AEM_NUMBER_OF_PROCESSES:-1}
depends_on:
kafka:
condition: service_healthy
Expand Down
13 changes: 13 additions & 0 deletions docs/Release_notes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
JPO-ODE Release Notes
----------------------------

Version 6.0.0, released May 2026
----------------------------------------
### **Summary**
This release expands support for existing jpo-ode functionality and improves flexibility in deployment and data handling. JSON schemas are now bundled within the jpo-asn-pojos submodule, enabling offline usage without external dependencies. Additionally, a receiving port remapping configuration has been introduced to better identify traffic sources that may not originate from an RSU. This release also includes several minor fixes.

Enhancements in this release:
- [ASN Hex 1609.2 Signature Retention (ITSA)](https://github.com/usdot-jpo-ode/jpo-ode/pull/596)
- [Submodule update to provide JSON schemas in resources for offline availability](https://github.com/neaeraconsulting/jpo-ode/pull/1)
- [Port remap receiver](https://github.com/neaeraconsulting/jpo-ode/pull/2)
- [Configurable kafka concurrency](https://github.com/neaeraconsulting/jpo-ode/pull/3)
- [Docker shared Kafka fix](https://github.com/neaeraconsulting/jpo-ode/pull/9)
- [Add env vars for number of ACM processes, update test process](https://github.com/neaeraconsulting/jpo-ode/pull/7)

Version 5.1.0, released October 2025
----------------------------------------
### **Summary**
Expand Down
1 change: 1 addition & 0 deletions docs/compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ This table serves as a guide, suggesting which versions of individual submodules

| [ODE (this project)](https://github.com/usdot-jpo-ode/jpo-ode/releases) | [ACM](https://github.com/usdot-jpo-ode/asn1_codec/releases) | [PPM](https://github.com/usdot-jpo-ode/jpo-cvdp/releases) | [SEC](https://github.com/usdot-jpo-ode/jpo-security-svcs/releases) | [SDWD](https://github.com/usdot-jpo-ode/jpo-sdw-depositor/releases) | [S3D](https://github.com/usdot-jpo-ode/jpo-s3-deposit/releases) | [GJConverter](https://github.com/usdot-jpo-ode/jpo-geojsonconverter/releases) | [CMonitor](https://github.com/usdot-jpo-ode/jpo-conflictmonitor/releases) | [CVisualizer](https://github.com/usdot-jpo-ode/jpo-conflictvisualizer/releases) | [CVManager](https://github.com/usdot-jpo-ode/jpo-cvmanager/releases) | [MEC](https://github.com/usdot-jpo-ode/jpo-mec-deposit/releases) |
|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
| 6.0.0 | 3.3.0 | 1.6.0 | 1.7.0 | 1.10.0 | 1.7.1 | 3.3.0 | 3.2.0 | N/A | 2.1.0 | 1.1.0 |
| 5.1.0 | 3.2.0 | 1.6.0 | 1.7.0 | 1.10.0 | 1.7.1 | 3.2.0 | 3.1.0 | N/A | 2.0.0 | 1.0.0 |
| 4.1.2 | 3.1.0 | 1.5.0 | 1.6.0 | 1.9.1 | 1.7.1 | 2.1.0 | 2.1.0 | 1.5.0 | 1.6.0 | N/A |
| 4.0.0 | 3.0.0 | 1.5.0 | 1.5.0 | 1.9.0 | 1.7.0 | 2.0.0 | 2.0.0 | 1.5.0 | 1.5.0 | N/A |
Expand Down
29 changes: 28 additions & 1 deletion docs/release_process_quarterly.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,31 @@ None
- [ ] messages get decoded as expected
- [ ] messages get encoded as expected

#### Details on how to do tests

Run compilation and unit tests in Docker: From the root directory of asn1_codec issue:
```
docker build -t acm .
docker run --env-file .env --name acm -it acm
```
In a separate shell:
```
docker exec -it acm bash
/build/acm_tests
```

where the `.env` file is configured with necessary environment variables.

To test program startup and encoding/decoding:

Pull the release branch into the ODE submodule, and run the ODE via `docker compose up --build -d` from the jpo-ode root directory, with the following profiles set in the `.env` file:
```
COMPOSE_PROFILES=ode,adm,aem,kafka,kafka_setup,kafka_ui
```
To test decoding send test messages with the `udpsender_generic.py` script and verify the messages are decoded by looking at the `topic.Asn1DecoderOutput` in the kafka UI.

To test encoding, use the Kafka UI to produce one of the decoded messages from `topic.Asn1DecoderOutput` to `topic.Asn1EncoderInput` and check the decoded output appears on `topic.Asn1EncoderOutput`.

### 3. Project Reference Updates & Release Creation
- [ ] Merge ‘release/(year)-(quarter)’ branch into ‘master’ branch for the asn1_codec project
- [ ] Create a release for the asn1_codec project from the ‘master’ branch and tag the release with the version number of the release. (e.g. asn1_codec-x.x.x)
Expand Down Expand Up @@ -220,11 +245,13 @@ None
- [ ] code compiles
- gradle build
- [ ] `jpo-asn-j2735-2024` subproject builds via gradle
- [ ] `jpo-asn-test-generator` subproject build via gradle
- [ ] `jpo-asn-test-generator` subproject builds via gradle
- [ ] `jpo-asn-jsonschema-generator` subproject builds via gradle
- maven build:
- [ ] `jpo-asn-j2735-2024` subproject builds via maven
- [ ] unit tests pass
- [ ] test generator command line tool can generate messages
- [ ] schema generator command line tool can generate schemas

### 3. Project Reference Updates & Release Creation
- [ ] Update Gradle build version number
Expand Down
2 changes: 1 addition & 1 deletion jpo-asn-pojos
Submodule jpo-asn-pojos updated 21 files
+110 −76 .github/workflows/ci.yml
+5 −0 .gitignore
+3 −0 README.md
+12 −0 docs/Release_notes.md
+1 −1 jpo-asn-j2735-2024/build.gradle
+2 −2 jpo-asn-j2735-2024/pom.xml
+1,560 −0 jpo-asn-j2735-2024/src/main/resources/schemas/BasicSafetyMessage/BasicSafetyMessageMessageFrame.schema.json
+3,777 −0 jpo-asn-j2735-2024/src/main/resources/schemas/MapData/MapDataMessageFrame.schema.json
+42,521 −0 jpo-asn-j2735-2024/src/main/resources/schemas/MessageFrame/MessageFrame.schema.json
+1,020 −0 ...n-j2735-2024/src/main/resources/schemas/PersonalSafetyMessage/PersonalSafetyMessageMessageFrame.schema.json
+426 −0 jpo-asn-j2735-2024/src/main/resources/schemas/RTCMcorrections/RTCMcorrectionsMessageFrame.schema.json
+9,407 −0 jpo-asn-j2735-2024/src/main/resources/schemas/RoadSafetyMessage/RoadSafetyMessageMessageFrame.schema.json
+1,255 −0 jpo-asn-j2735-2024/src/main/resources/schemas/SPAT/SPATMessageFrame.schema.json
+1,183 −0 ...5-2024/src/main/resources/schemas/SensorDataSharingMessage/SensorDataSharingMessageMessageFrame.schema.json
+746 −0 ...asn-j2735-2024/src/main/resources/schemas/SignalRequestMessage/SignalRequestMessageMessageFrame.schema.json
+479 −0 jpo-asn-j2735-2024/src/main/resources/schemas/SignalStatusMessage/SignalStatusMessageMessageFrame.schema.json
+4,558 −0 jpo-asn-j2735-2024/src/main/resources/schemas/TravelerInformation/TravelerInformationMessageFrame.schema.json
+5 −2 jpo-asn-runtime/build.gradle
+1 −1 jpo-asn-runtime/pom.xml
+1 −1 pom.xml
+38 −0 sonar-project.properties
24 changes: 13 additions & 11 deletions jpo-ode-common/pom.xml
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>usdot.jpo.ode</groupId>
<artifactId>jpo-ode</artifactId>
<version>5.1.0</version>
<version>6.0.0</version>
</parent>

<artifactId>jpo-ode-common</artifactId>
<name>jpo-ode-common</name>
<description>JPO ODE Common Components</description>
<packaging>jar</packaging>

<properties>
<!-- SonarQube Properties -->
<sonar.exclusions>src/main/java/us/dot/its/jpo/ode/util/GeoUtils.java</sonar.exclusions>
Expand All @@ -21,26 +23,26 @@
<sonar.inclusions>src/main/java/us/dot/its/jpo/ode/inet/*</sonar.inclusions>
</properties>


<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
<version>20231013</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>4.0.0</version>
</dependency>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-client-api</artifactId>
Expand All @@ -52,4 +54,4 @@
<version>4.0.0</version>
</dependency>
</dependencies>
</project>
</project>
10 changes: 5 additions & 5 deletions jpo-ode-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>usdot.jpo.ode</groupId>
<artifactId>jpo-ode</artifactId>
<version>5.1.0</version>
<version>6.0.0</version>
</parent>

<artifactId>jpo-ode-core</artifactId>
Expand All @@ -25,12 +25,12 @@
<dependency>
<groupId>usdot.jpo.ode</groupId>
<artifactId>jpo-ode-common</artifactId>
<version>5.1.0</version>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>usdot.jpo.ode</groupId>
<artifactId>jpo-ode-plugins</artifactId>
<version>5.1.0</version>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
Expand Down Expand Up @@ -90,13 +90,13 @@
<dependency>
<groupId>com.networknt</groupId>
<artifactId>json-schema-validator</artifactId>
<version>1.0.76</version>
<version>1.0.88</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>usdot.jpo.asn</groupId>
<artifactId>jpo-asn-j2735-2024</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
</dependency>
</dependencies>

Expand Down
10 changes: 6 additions & 4 deletions jpo-ode-plugins/pom.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<artifactId>jpo-ode-plugins</artifactId>
Expand All @@ -11,7 +13,7 @@
<parent>
<groupId>usdot.jpo.ode</groupId>
<artifactId>jpo-ode</artifactId>
<version>5.1.0</version>
<version>6.0.0</version>
</parent>
<properties>
<!-- SonarQube Properties -->
Expand All @@ -27,7 +29,7 @@
<dependency>
<groupId>usdot.jpo.ode</groupId>
<artifactId>jpo-ode-common</artifactId>
<version>5.1.0</version>
<version>6.0.0</version>
</dependency>
<!-- TODO open-ode
<dependency>
Expand All @@ -39,4 +41,4 @@
</dependencies>


</project>
</project>
10 changes: 5 additions & 5 deletions jpo-ode-svcs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>usdot.jpo.ode</groupId>
<artifactId>jpo-ode</artifactId>
<version>5.1.0</version>
<version>6.0.0</version>
</parent>
<artifactId>jpo-ode-svcs</artifactId>
<packaging>jar</packaging>
Expand Down Expand Up @@ -127,12 +127,12 @@
<dependency>
<groupId>usdot.jpo.ode</groupId>
<artifactId>jpo-ode-core</artifactId>
<version>5.1.0</version>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>usdot.jpo.ode</groupId>
<artifactId>jpo-ode-plugins</artifactId>
<version>5.1.0</version>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
Expand All @@ -156,13 +156,13 @@
<dependency>
<groupId>com.networknt</groupId>
<artifactId>json-schema-validator</artifactId>
<version>1.0.76</version>
<version>1.0.88</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>usdot.jpo.asn</groupId>
<artifactId>jpo-asn-j2735-2024</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>net.javacrumbs.json-unit</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
import org.springframework.boot.autoconfigure.kafka.KafkaProperties.Listener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.EnableKafka;
Expand Down Expand Up @@ -65,6 +66,11 @@ public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerCont
ConcurrentKafkaListenerContainerFactory<String, String> factory =
new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());

// Set concurrency
// Usually set to number of partitions per topic per ode app instance
factory.setConcurrency(kafkaProperties.getListener().getConcurrency());

return factory;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import us.dot.its.jpo.ode.udp.bsm.BsmReceiver;
import us.dot.its.jpo.ode.udp.generic.GenericReceiver;
import us.dot.its.jpo.ode.udp.map.MapReceiver;
import us.dot.its.jpo.ode.udp.portmapped.PortMappedIngestConfigLoader;
import us.dot.its.jpo.ode.udp.psm.PsmReceiver;
import us.dot.its.jpo.ode.udp.rsm.RsmReceiver;
import us.dot.its.jpo.ode.udp.rtcm.RtcmReceiver;
Expand Down Expand Up @@ -44,7 +45,8 @@ public class UdpServicesController {
@Autowired
public UdpServicesController(UDPReceiverProperties udpProps,
RawEncodedJsonTopics rawEncodedJsonTopics,
KafkaTemplate<String, String> kafkaTemplate) {
KafkaTemplate<String, String> kafkaTemplate,
PortMappedIngestConfigLoader portMappedIngestConfigLoader) {

log.debug("Starting UDP receiver services...");

Expand All @@ -60,6 +62,13 @@ public UdpServicesController(UDPReceiverProperties udpProps,
startReceiver(new RsmReceiver(udpProps.getRsm(), kafkaTemplate, rawEncodedJsonTopics.getRsm()));
startReceiver(new GenericReceiver(udpProps.getGeneric(), kafkaTemplate, rawEncodedJsonTopics));


List<AbstractUdpReceiverPublisher> receivers = portMappedIngestConfigLoader
.loadReceivers(udpProps, rawEncodedJsonTopics, kafkaTemplate);
for (AbstractUdpReceiverPublisher receiver : receivers) {
startReceiver(receiver);
}

log.debug("UDP receiver services started.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ private static String describePacketForLog(DatagramPacket packet) {
return sb.toString();
}

private void routeMessageByMessageType(String messageType, DatagramPacket packet)
protected void routeMessageByMessageType(String messageType, DatagramPacket packet)
throws InvalidPayloadException, UnsupportedMessageTypeException {
log.debug("Detected Message Type {}", messageType);
switch (messageType) {
Expand Down
Loading
Loading