Skip to content

Commit

Permalink
Merge branch 'develop' into open-ode
Browse files Browse the repository at this point in the history
  • Loading branch information
hmusavi committed Apr 23, 2018
2 parents 1c59b78 + 975a82e commit cc0e7ac
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 21 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ Master: [![Build Status](https://travis-ci.org/usdot-jpo-ode/jpo-ode.svg?branch=
Develop: [![Build Status](https://travis-ci.org/usdot-jpo-ode/jpo-ode.svg?branch=develop)](https://travis-ci.org/usdot-jpo-ode/jpo-ode) [![Quality Gate](https://sonarcloud.io/api/badges/gate?key=usdot.jpo.ode:jpo-ode:develop)](https://sonarcloud.io/dashboard?id=usdot.jpo.ode%3Ajpo-ode%3Adevelop)

# jpo-ode
US Department of Transportation Joint Program office (JPO) Operational Data Environment (ODE)
US Department of Transportation (USDOT) Intelligent Transportation Systems Operational Data Environment (ITS ODE)

In the context of ITS, an Operational Data Environment is a real-time data acquisition and distribution software system that processes and routes data from Connected-X devices including connected vehicles (CV), personal mobile devices, and infrastructure components and sensors –to subscribing applications to support the operation, maintenance, and use of the transportation system, as well as related research and development efforts.
The ITS ODE is a real-time virtual data router that ingests and processes operational data from various connected devices - including vehicles, infrastructure, and traffic management centers - and distributes it to other devices and subscribing transportation management applications. Using the ITS ODE within intelligent transportation deployments increases data fluidity and interoperability while meeting operational needs and protecting user privacy. The software’s microservices architecture makes it easy to add new capabilities to meet local needs.

![ODE Dataflows](images/data_flow_v2.png)

Expand Down
7 changes: 6 additions & 1 deletion docs/ODESwagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,12 @@ definitions:
type: string
description: >-
Eight-digit hex code of the groupID to use, for example "A123B456".
GroupID is used
GroupID is a DSRC.TemporaryID used for message identification.
recordID:
type: string
description: >-
Eight-digit hex code of the recordID to use, for example "A123B456".
RecordID is a DSRC.TemporaryID used for message identification.
ttl:
type: string
description: Message time to live.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ public static long[] bytesToLongs(byte[] bytes, int offset, int length, ByteOrde
public static String toHex(byte[] bytes) {
return bytes != null ? DatatypeConverter.printHexBinary(bytes) : "";
}

public static String toHex(byte b) {
return DatatypeConverter.printHexBinary(new byte[]{b});
}

public static byte[] fromHex(String hex) {
return DatatypeConverter.parseHexBinary(hex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public enum TimeToLive {
private String groupID = null;
private String deliverystart;
private String deliverystop;
private String recordId = null;

public OdeGeoRegion getServiceRegion() {
return serviceRegion;
Expand Down Expand Up @@ -64,13 +65,22 @@ public void setDeliverystart(String deliverystart) {
this.deliverystart = deliverystart;
}

public String getRecordId() {
return recordId;
}

public void setRecordId(String recordId) {
this.recordId = recordId;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((deliverystart == null) ? 0 : deliverystart.hashCode());
result = prime * result + ((deliverystop == null) ? 0 : deliverystop.hashCode());
result = prime * result + ((groupID == null) ? 0 : groupID.hashCode());
result = prime * result + ((recordId == null) ? 0 : recordId.hashCode());
result = prime * result + ((serviceRegion == null) ? 0 : serviceRegion.hashCode());
result = prime * result + ((ttl == null) ? 0 : ttl.hashCode());
return result;
Expand Down Expand Up @@ -100,6 +110,11 @@ public boolean equals(Object obj) {
return false;
} else if (!groupID.equals(other.groupID))
return false;
if (recordId == null) {
if (other.recordId != null)
return false;
} else if (!recordId.equals(other.recordId))
return false;
if (serviceRegion == null) {
if (other.serviceRegion != null)
return false;
Expand All @@ -109,6 +124,8 @@ public boolean equals(Object obj) {
return false;
return true;
}


}
private SituationDataWarehouse() {
throw new UnsupportedOperationException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,10 @@ public enum AdvisoryBroadcastType {
tim, // (2),
ev // (3),
}

public enum DistributionType {
none, //(0), "00000000", not intended for redistribution
rsu, //(1), "00000001", intended for redistribution over DSRC
ip //(2), "00000010" intended for redistribution over IP
}

String asdmID; // DSRC.TemporaryID,
int asdmType; // AdvisoryBroadcastType,
int distType; //0, 1 or 2 ,
String distType; //0, 1 or 2 ,
J2735DFullTime startTime; //OPTIONAL,
J2735DFullTime stopTime; //OPTIONAL,
String advisoryMessageBytes; // OCTET STRING (SIZE(0..1400)) -- Encoded advisory message
Expand All @@ -37,7 +31,7 @@ public String getAsdmID() {
return asdmID;
}

public DdsAdvisoryDetails(String asdmID, AdvisoryBroadcastType asdmType, int distType, J2735DFullTime startTime,
public DdsAdvisoryDetails(String asdmID, AdvisoryBroadcastType asdmType, String distType, J2735DFullTime startTime,
J2735DFullTime stopTime, Ieee1609Dot2DataTag advisoryMessage2) {
super();
this.asdmID = asdmID;
Expand All @@ -57,10 +51,10 @@ public int getAsdmType() {
public void setAsdmType(int asdmType) {
this.asdmType = asdmType;
}
public int getDistType() {
public String getDistType() {
return distType;
}
public void setDistType(int distType) {
public void setDistType(String distType) {
this.distType = distType;
}
public J2735DFullTime getStartTime() {
Expand All @@ -87,6 +81,8 @@ public Ieee1609Dot2DataTag getAdvisoryMessage() {
public void setAdvisoryMessage(Ieee1609Dot2DataTag advisoryMessage) {
this.advisoryMessage = advisoryMessage;
}


@Override
public int hashCode() {
final int prime = 31;
Expand All @@ -95,11 +91,13 @@ public int hashCode() {
result = prime * result + ((advisoryMessageBytes == null) ? 0 : advisoryMessageBytes.hashCode());
result = prime * result + ((asdmID == null) ? 0 : asdmID.hashCode());
result = prime * result + asdmType;
result = prime * result + distType;
result = prime * result + ((distType == null) ? 0 : distType.hashCode());
result = prime * result + ((startTime == null) ? 0 : startTime.hashCode());
result = prime * result + ((stopTime == null) ? 0 : stopTime.hashCode());
return result;
}


@Override
public boolean equals(Object obj) {
if (this == obj)
Expand All @@ -126,7 +124,10 @@ public boolean equals(Object obj) {
return false;
if (asdmType != other.asdmType)
return false;
if (distType != other.distType)
if (distType == null) {
if (other.distType != null)
return false;
} else if (!distType.equals(other.distType))
return false;
if (startTime == null) {
if (other.startTime != null)
Expand All @@ -142,4 +143,5 @@ public boolean equals(Object obj) {
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
import us.dot.its.jpo.ode.plugin.asn1.Asn1Object;
import us.dot.its.jpo.ode.plugin.ieee1609dot2.Ieee1609Dot2DataTag;
import us.dot.its.jpo.ode.plugin.j2735.DdsAdvisoryDetails.AdvisoryBroadcastType;
import us.dot.its.jpo.ode.plugin.j2735.DdsAdvisoryDetails.DistributionType;
import us.dot.its.jpo.ode.util.CodecUtils;
import us.dot.its.jpo.ode.util.DateTimeUtils;

public class DdsAdvisorySituationData extends Asn1Object {
private static final long serialVersionUID = 2755274323293805425L;

// Distribution Type field values
public static final byte NONE = (byte) 0x00;
public static final byte RSU = (byte) 0x01;
public static final byte IP = (byte) 0x02;

private int dialogID = 0x9C; // SemiDialogID -- 0x9C Advisory Situation Data Deposit
private int seqID = 0x05; // SemiSequenceID -- 0x05 Data
Expand All @@ -35,7 +39,7 @@ public DdsAdvisorySituationData() {
}

public DdsAdvisorySituationData(String startTime, String stopTime, Ieee1609Dot2DataTag advisoryMessage,
DdsGeoRegion serviceRegion, SituationDataWarehouse.SDW.TimeToLive ttl, String groupID) throws ParseException {
DdsGeoRegion serviceRegion, SituationDataWarehouse.SDW.TimeToLive ttl, String groupID, String recordID, byte distroType) throws ParseException {
this();

J2735DFullTime dStartTime = dFullTimeFromIsoTimeString(startTime);
Expand All @@ -45,9 +49,9 @@ public DdsAdvisorySituationData(String startTime, String stopTime, Ieee1609Dot2D
byte[] fourRandomBytes = new byte[4];
new Random(System.currentTimeMillis()).nextBytes(fourRandomBytes);
String id = CodecUtils.toHex(fourRandomBytes);
int distroType = DistributionType.rsu.ordinal();
String stringDistroType = CodecUtils.toHex(distroType);
this.setAsdmDetails(
new DdsAdvisoryDetails(id, AdvisoryBroadcastType.tim, distroType, dStartTime, dStopTime, advisoryMessage));
new DdsAdvisoryDetails(id, AdvisoryBroadcastType.tim, stringDistroType, dStartTime, dStopTime, advisoryMessage));

this.setRequestID(id);
this.setServiceRegion(serviceRegion);
Expand All @@ -61,6 +65,11 @@ public DdsAdvisorySituationData(String startTime, String stopTime, Ieee1609Dot2D
} else {
this.setGroupID(CodecUtils.toHex(new byte[] { 0, 0, 0, 0 }));
}
if (recordID != null) {
this.setRecordID(recordID);
} else {
this.setRecordID(CodecUtils.toHex(new byte[] { 0, 0, 0, 0 }));
}
}

private J2735DFullTime dFullTimeFromIsoTimeString(String isoTime) throws ParseException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package us.dot.its.jpo.ode.plugin.j2735;

import static org.junit.Assert.*;

import org.junit.Test;

import mockit.Tested;
import us.dot.its.jpo.ode.plugin.ieee1609dot2.Ieee1609Dot2DataTag;
import us.dot.its.jpo.ode.plugin.j2735.DdsAdvisoryDetails.AdvisoryBroadcastType;
import us.dot.its.jpo.ode.util.CodecUtils;

public class DdsAdvisoryDetailsTest {

@Tested
DdsAdvisoryDetails testDdsAdvisoryDetails;

@Test
public void testSettersGetters() {
testDdsAdvisoryDetails.setAsdmID("testAsdmID");
testDdsAdvisoryDetails.setAsdmType(1);
testDdsAdvisoryDetails.setDistType(CodecUtils.toHex(DdsAdvisorySituationData.IP));
testDdsAdvisoryDetails.setStartTime(new J2735DFullTime());
testDdsAdvisoryDetails.setStopTime(new J2735DFullTime());
testDdsAdvisoryDetails.setAdvisoryMessageBytes("testAdvisoryMessageBytes");
testDdsAdvisoryDetails.setAdvisoryMessage(new Ieee1609Dot2DataTag());

assertEquals("testAsdmID", testDdsAdvisoryDetails.getAsdmID());
assertEquals(1, testDdsAdvisoryDetails.getAsdmType());
assertEquals("02", testDdsAdvisoryDetails.getDistType());
assertNotNull(testDdsAdvisoryDetails.getStartTime());
assertNotNull(testDdsAdvisoryDetails.getStopTime());
assertEquals("testAdvisoryMessageBytes", testDdsAdvisoryDetails.getAdvisoryMessageBytes());
assertNotNull(testDdsAdvisoryDetails.getAdvisoryMessage());
}

@Test
public void testHashCodeAndEquals() {
String distType = CodecUtils.toHex(DdsAdvisorySituationData.RSU);

DdsAdvisoryDetails ddsad1 = new DdsAdvisoryDetails("asdmID", AdvisoryBroadcastType.tim, distType, new J2735DFullTime(),
new J2735DFullTime(), new Ieee1609Dot2DataTag());
DdsAdvisoryDetails ddsad2 = new DdsAdvisoryDetails("asdmID", AdvisoryBroadcastType.tim, distType, new J2735DFullTime(),
new J2735DFullTime(), new Ieee1609Dot2DataTag());
DdsAdvisoryDetails ddsad3 = new DdsAdvisoryDetails("asdmID", AdvisoryBroadcastType.map, distType, new J2735DFullTime(),
new J2735DFullTime(), new Ieee1609Dot2DataTag());

assertEquals("Expected identical hashcodes", ddsad1.hashCode(), ddsad2.hashCode());
assertNotEquals("Expected different hashcodes", ddsad2.hashCode(), ddsad3.hashCode());

assertTrue("Expected objects to be equal", ddsad1.equals(ddsad2));
assertFalse("Expected objects to not be equal", ddsad2.equals(ddsad3));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -313,15 +313,18 @@ public ResponseEntity<String> depositTim(String jsonString, int verb) {
ieee.setContent(ieeeContent );
ieeeDataTag.setIeee1609Dot2Data(ieee);

byte sendToRsu = travelerInputData.getRsus() != null ? DdsAdvisorySituationData.RSU:DdsAdvisorySituationData.NONE;
byte distroType = (byte) (DdsAdvisorySituationData.IP | sendToRsu);

// take deliverystart and stop times from SNMP object, if present
// else take from SDW object
SNMP snmp = travelerInputData.getSnmp();
if (null != snmp) {
asd = new DdsAdvisorySituationData(snmp.getDeliverystart(), snmp.getDeliverystop(), ieeeDataTag,
GeoRegionBuilder.ddsGeoRegion(sdw.getServiceRegion()), sdw.getTtl(), sdw.getGroupID());
GeoRegionBuilder.ddsGeoRegion(sdw.getServiceRegion()), sdw.getTtl(), sdw.getGroupID(), sdw.getRecordId(), distroType);
} else {
asd = new DdsAdvisorySituationData(sdw.getDeliverystart(), sdw.getDeliverystop(), ieeeDataTag,
GeoRegionBuilder.ddsGeoRegion(sdw.getServiceRegion()), sdw.getTtl(), sdw.getGroupID());
GeoRegionBuilder.ddsGeoRegion(sdw.getServiceRegion()), sdw.getTtl(), sdw.getGroupID(), sdw.getRecordId(), distroType);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public class AsdMessageTest {
SituationDataWarehouse.SDW.TimeToLive ttl = SituationDataWarehouse.SDW.TimeToLive.oneminute;
@Injectable
String groupID = "01234567";
@Injectable
byte distroType = DdsAdvisorySituationData.NONE;
@Injectable
String recordID = "76543210";

@Mocked
ZonedDateTime mockZonedDateTimeStart;
Expand Down

0 comments on commit cc0e7ac

Please sign in to comment.